﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using JasLib.Extensions;
using Microsoft.Win32.SafeHandles;

namespace JasLib.Interop.Win32
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct BINDINFO
    {
        public uint cbSize;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szExtraInfo;
        public /*STGMEDIUM*/UINT_PTR stgmedData;
        public BINDINFOF grfBindInfoF;
        public BINDVERB dwBindVerb;
        [MarshalAs(UnmanagedType.BStr)]
        public string szCustomVerb;
        public uint cbStgmedData;
        public BINDINFO_OPTIONS dwOptions;
        public uint dwOptionsFlags;
        public uint dwCodePage;
        public SECURITY_ATTRIBUTES securityAttributes;
        public Guid iid;
        public IUnknown pUnk;
        public uint dwReserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct BROWSEINFO
    {
        public HWND hwndOwner;
        public UINT_PTR pidlRoot;
        public UINT_PTR pszDisplayName;        // Return display name of item selected.
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpszTitle;                     // text to go in the banner over the tree.
        public BrowseInfoFlags ulFlags;                       // Flags that control the return stuff
        /// <summary>Pointer to function of type BFFCALLBACK.</summary>
        public UINT_PTR lpfn;
        public INT_PTR lParam;                        // extra info that's passed back in callbacks
        public int iImage;                        // output var: where to return the Image index.
    }

    /// <summary>
    /// http://msdn.microsoft.com/en-us/library/bb773212.aspx
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct CIDA
    {
        public uint cidl;
        public fixed uint aoffset[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size = 24)]
    public struct CLASSIC_EVENT_ID
    {
        [MarshalAs(UnmanagedType.Struct)]
        public Guid EventGuid;
        public byte Type;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
        public byte[] Reserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct CMINVOKECOMMANDINFO
    {
        public uint cbSize;
        public uint fMask;
        public HWND hwnd;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpVerb;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpParameters;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpDirectory;
        public ShowWindowCommand nShow;
        public uint dwHotKey;
        public HICON hIcon;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct CMINVOKECOMMANDINFOEX
    {
        public uint cbSize;
        public uint fMask;
        public HWND hwnd;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpVerb;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpParameters;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpDirectory;
        public ShowWindowCommand nShow;
        public uint dwHotKey;
        public HICON hIcon;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpTitle;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpVerbW;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpParametersW;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpDirectoryW;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpTitleW;
        public POINT ptInvoke;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COAUTHIDENTITY
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string User;
        public uint UserLength;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string Domain;
        public uint DomainLength;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string Password;
        public uint PasswordLength;
        public uint Flags;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COAUTHINFO
    {
        public uint dwAuthnSvc;
        public uint dwAuthzSvc;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pwszServerPrincName;
        public uint dwAuthnLevel;
        public uint dwImpersonationLevel;
        /// <summary>
        /// Pointer to a COAUTHIDENTITY.
        /// </summary>
        public UINT_PTR pAuthIdentityData;
        public uint dwCapabilities;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COLORREF
    {
        /// <summary>
        /// 0x00BBGGRR format.
        /// </summary>
        private uint _value;

        public byte R
        {
            get { return (byte)(_value & 0xFF); }
            set { _value = (uint)((_value & 0xFFFFFF00) | (value)); }
        }

        public byte G
        {
            get { return (byte)((_value >> 8) & 0xFF); }
            set { _value = (uint)((_value & 0xFFFF00FF) | (uint)(value << 8)); }
        }

        public byte B
        {
            get { return (byte)((_value >> 16) & 0xFF); }
            set { _value = (uint)((_value & 0xFF00FFFF) | (uint)(value << 16)); }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COMDLG_FILTERSPEC
    {
        public COMDLG_FILTERSPEC(string new_pszName = null, string new_pszSpec = null)
        {
            pszName = new_pszName;
            pszSpec = new_pszSpec;
            return;
        }

        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszSpec;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COORD
    {
        public short X;
        public short Y;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COPYDATASTRUCT
    {
        public UINT_PTR dwData;
        public uint cbData;
        public UINT_PTR buffer;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct COSERVERINFO
    {
        public uint dwReserved1;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pwszName;
        /// <summary>
        /// Pointer to a COAUTHINFO.
        /// </summary>
        public UINT_PTR pAuthInfo;
        private uint dwReserved2;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("hwnd={hwnd}, message={message}, wParam={wParam}, lParam={lParam}, lResult={lResult}")]
    public struct CWPRETSTRUCT
    {
        public INT_PTR lResult;
        public INT_PTR lParam;
        public UINT_PTR wParam;
        public WindowMessageId message;
        public HWND hwnd;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("hwnd={hwnd}, message={message}, wParam={wParam}, lParam={lParam}")]
    public struct CWPSTRUCT
    {
        public INT_PTR lParam;
        public UINT_PTR wParam;
        public WindowMessageId message;
        public HWND hwnd;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct DECIMAL
    {
        [FieldOffset(0)]
        public ushort wReserved;

        [FieldOffset(2)]
        public ushort signscale;
        [FieldOffset(2)]
        public byte scale;
        [FieldOffset(3)]
        public byte sign;

        [FieldOffset(4)]
        public uint Hi32;

        [FieldOffset(8)]
        public ulong Lo64;
        [FieldOffset(8)]
        public uint Lo32;
        [FieldOffset(12)]
        public uint Mid32;

        public static readonly byte DECIMAL_NEG = 0x80;
        
        public void DECIMAL_SETZERO()
        {
            Lo64 = 0;
            Hi32 = 0; 
            signscale = 0;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct DLLVERSIONINFO
    {
        public int cbSize;
        public int dwMajorVersion;
        public int dwMinorVersion;
        public int dwBuildNumber;
        public int dwPlatformID;

        public override string ToString()
        {
            return string.Format("{0}.{1}.{2}", dwMajorVersion, dwMinorVersion, dwBuildNumber);
        }

        /// <summary>
        /// Because structs can't have explicit parameter-less constructors.
        /// </summary>
        public static DLLVERSIONINFO New()
        {
            DLLVERSIONINFO info = new DLLVERSIONINFO();
            info.cbSize = Marshal.SizeOf(typeof(DLLVERSIONINFO));
            return info;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct DLLVERSIONINFO2
    {
        public DLLVERSIONINFO info1;
        public uint dwFlags;
        public ulong ullVersion;

        /// <summary>
        /// http://msdn.microsoft.com/en-us/library/bb774312(v=VS.85).aspx
        /// </summary>
        public static ulong MAKEDLLVERULL(uint major, uint minor, uint build, uint sp)
        {
            return (((ulong)(major) << 48) | ((ulong)(minor) << 32) | ((ulong)(build) << 16) | ((ulong)(sp) << 0));
        }

        /// <summary>
        /// Because structs can't have explicit parameter-less constructors.
        /// </summary>
        public static DLLVERSIONINFO2 New()
        {
            DLLVERSIONINFO2 info = new DLLVERSIONINFO2();
            info.info1.cbSize = Marshal.SizeOf(typeof(DLLVERSIONINFO2));
            return info;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct DVTARGETDEVICE
    {
        public uint tdSize;
        public ushort tdDriverNameOffset;
        public ushort tdDeviceNameOffset;
        public ushort tdPortNameOffset;
        public ushort tdExtDevmodeOffset;
        public fixed byte tdData[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct DWM_BLURBEHIND
    {
        public DWM_BB dwFlags;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fEnable;
        public HRGN hRgnBlur;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fTransitionOnMaximized;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct ENABLE_TRACE_PARAMETERS
    {
        public uint Version;
        public uint EnableProperty;
        public uint ControlFlags;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid SourceId;
        public EVENT_FILTER_DESCRIPTOR EnableFilterDesc;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct ETW_BUFFER_CONTEXT
    {
        public byte ProcessorNumber;
        public byte Alignment;
        public ushort LoggerId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_DATA_DESCRIPTOR
    {
        public ulong Ptr;
        public uint Size;
        public uint Reserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_DESCRIPTOR
    {
        public ushort Id;
        public byte Version;
        public byte Channel;
        public byte Level;
        public byte Opcode;
        public byte Task;
        public ulong Keyword;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_EXTENDED_ITEM_INSTANCE
    {
        public uint InstanceId;
        public uint ParentInstanceId;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid ParentGuid;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_EXTENDED_ITEM_RELATED_ACTIVITYID
    {
        [MarshalAs(UnmanagedType.Struct)]
        public Guid RelatedActivityId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct EVENT_EXTENDED_ITEM_STACK_TRACE32
    {
        public ulong MatchId;
        public fixed uint Address[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct EVENT_EXTENDED_ITEM_STACK_TRACE64
    {
        public ulong MatchId;
        public fixed ulong Address[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_EXTENDED_ITEM_TS_ID
    {
        public uint SessionId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_FILTER_DESCRIPTOR
    {
        public ulong Ptr;
        public uint Size;
        public uint Type;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_FILTER_HEADER
    {
        public ushort Id;
        public byte Version;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public byte[] Reserved;
        public ulong InstanceId;
        public uint Size;
        public uint NextOffset;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_HEADER
    {
        public ushort Size;
        public ushort HeaderType;
        public ushort Flags;
        public ushort EventProperty;
        public uint ThreadId;
        public uint ProcessId;
        public LARGE_INTEGER TimeStamp;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid ProviderId;
        public EVENT_DESCRIPTOR EventDescriptor;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME
            {
                public uint KernelTime;
                public uint UserTime;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME DUMMYSTRUCTNAME;

            [FieldOffset(0)]
            public ulong ProcessorTime;
        }
        [MarshalAs(UnmanagedType.Struct)]
        public Guid ActivityId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_HEADER_EXTENDED_DATA_ITEM
    {
        public ushort Reserved1;
        public EventHeaderExtendedType ExtType;

        private ushort _bitfield;
        public ushort Linkage
        {
            get { return (ushort)(_bitfield & 1); }
        }

        public ushort DataSize;
        public ulong DataPtr;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_INSTANCE_HEADER
    {
        public ushort Size;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME
        {
            [FieldOffset(0)]
            public ushort FieldTypeFlags;

            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME
            {
                public byte HeaderType;
                public byte MarkerFlags;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME DUMMYSTRUCTNAME;
        }
        public _DUMMYUNIONNAME DUMMYUNIONNAME;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME2
        {
            [FieldOffset(0)]
            public uint Version;

            [StructLayout(LayoutKind.Sequential)]
            public struct _Class
            {
                public TraceType Type;
                public TraceLevel Level;
                public ushort Version;
            }
            [FieldOffset(0)]
            public _Class Class;
        }
        public _DUMMYUNIONNAME2 DUMMYUNIONNAME2;

        public uint ThreadId;
        public uint ProcessId;
        public LARGE_INTEGER TimeStamp;
        public ulong RegHandle;
        public uint InstanceId;
        public uint ParentInstanceId;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME3
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME
            {
                public uint KernelTime;
                public uint UserTime;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME DUMMYSTRUCTNAME;

            [FieldOffset(0)]
            public ulong ProcessorTime;

            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME2
            {
                public uint EventId;
                public uint Flags;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME2 DUMMYSTRUCTNAME2;
        }
        public _DUMMYUNIONNAME3 DUMMYUNIONNAME3;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_INSTANCE_INFO
    {
        public HANDLE RegHandle;
        public uint InstanceId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_RECORD
    {
        public EVENT_HEADER EventHeader;
        public ETW_BUFFER_CONTEXT BufferContext;
        public ushort ExtendedDataCount;
        public ushort UserDataLength;
        public EVENT_HEADER_EXTENDED_DATA_ITEM ExtendedData;
        public UINT_PTR UserData;
        public UINT_PTR UserContext;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_TRACE
    {
        public EVENT_TRACE_HEADER Header;
        public uint InstanceId;
        public uint ParentInstanceId;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid ParentGuid;
        public UINT_PTR MofData;
        public uint MofLength;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME
        {
            [FieldOffset(0)]
            public uint ClientContext;
            [FieldOffset(0)]
            public ETW_BUFFER_CONTEXT BufferContext;
        }
        public _DUMMYUNIONNAME DUMMYUNIONNAME;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_TRACE_HEADER
    {
        public ushort Size;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME
        {
            [FieldOffset(0)]
            public ushort FieldTypeFlags;

            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME
            {
                public byte HeaderType;
                public byte MarkerFlags;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME DUMMYSTRUCTNAME;
        }
        public _DUMMYUNIONNAME DUMMYUNIONNAME;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME2
        {
            [FieldOffset(0)]
            public uint Version;

            [StructLayout(LayoutKind.Sequential)]
            public struct _Class
            {
                public TraceType Type;
                public TraceLevel Level;
                public ushort Version;
            }
            [FieldOffset(0)]
            public _Class Class;
        }
        public _DUMMYUNIONNAME2 DUMMYUNIONNAME2;

        public uint ThreadId;
        public uint ProcessId;
        public LARGE_INTEGER TimeStamp;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME3
        {
            [FieldOffset(0)]
            public Guid Guid;
            [FieldOffset(0)]
            public ulong GuidPtr;
        }
        public _DUMMYUNIONNAME3 DUMMYUNIONNAME3;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME4
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME
            {
                public uint ClientContext;
                public uint Flags;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME DUMMYSTRUCTNAME;

            [FieldOffset(0)]
            public ulong ProcessorTime;

            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME2
            {
                public uint KernelTime;
                public uint UserTime;
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME2 DUMMYSTRUCTNAME2;
        }
        public _DUMMYUNIONNAME4 DUMMYUNIONNAME4;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_TRACE_LOGFILE
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string LogFileName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string LoggerName;
        public ulong CurrentTime;
        public uint BuffersRead;

        [StructLayout(LayoutKind.Explicit)]
        public struct __union1
        {
            [FieldOffset(0)]
            public uint LogFileMode;
            [FieldOffset(0)]
            public uint ProcessTraceMode;
        }
        public __union1 _union1;

        public EVENT_TRACE CurrentEvent;
        public TRACE_LOGFILE_HEADER LogfileHeader;
        /// <summary>Pointer to delegate of EVENT_TRACE_BUFFER_CALLBACK.</summary>
        public UINT_PTR BufferCallback;
        public uint BufferSize;
        public uint Filled;
        public uint EventsLost;

        [StructLayout(LayoutKind.Explicit)]
        public struct __union2
        {
            [FieldOffset(0)]
            public UINT_PTR EventCallback;
            [FieldOffset(0)]
            public UINT_PTR EventRecordCallback;
        }
        public __union2 _union2;

        public uint IsKernelTrace;
        public UINT_PTR Context;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENT_TRACE_PROPERTIES
    {
        public WNODE_HEADER Wnode;
        public uint BufferSize;
        public uint MinimumBuffers;
        public uint MaximumBuffers;
        public uint MaximumFileSize;
        public uint LogFileMode;
        public uint FlushTimer;
        public uint EnableFlags;
        public int AgeLimit;
        public uint NumberOfBuffers;
        public uint FreeBuffers;
        public uint EventsLost;
        public uint BuffersWritten;
        public uint LogBuffersLost;
        public uint RealTimeBuffersLost;
        public HANDLE LoggerThreadId;
        public uint LogFileNameOffset;
        public uint LoggerNameOffset;
    }

    [DebuggerDisplay("hwnd={hwnd}, message={message}, paramL={paramL}, paramH={paramH}, time={time}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EVENTMSG
    {
        public WindowMessageId message;
        public uint paramL;
        public uint paramH;
        public uint time;
        public HWND hwnd;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct EXCEPINFO
    {
        public ushort wCode;
        public ushort wReserved;
        [MarshalAs(UnmanagedType.BStr)]
        public string bstrSource;
        [MarshalAs(UnmanagedType.BStr)]
        public string bstrDescription;
        [MarshalAs(UnmanagedType.BStr)]
        public string bstrHelpFile;
        public uint dwHelpContext;
        public UINT_PTR pvReserved;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public EXCEPINFO_pfnDeferredFillIn pfnDeferredFillIn;
        public SCODE scode;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct FILE_ID_DESCRIPTOR
    {
        [FieldOffset(0)]
        public uint dwSize;
        [FieldOffset(4)]
        public FILE_ID_TYPE Type;
        [FieldOffset(12)]
        public LARGE_INTEGER FileId;
        [FieldOffset(12), MarshalAs(UnmanagedType.Struct)]
        public Guid ObjectId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct FILETIME
    {
        public uint dwLowDateTime;
        public uint dwHighDateTime;

        public static implicit operator FILETIME(long value)
        {
            return new FILETIME
            {
                dwLowDateTime = (uint)((ulong)value & 0xFFFFFFFF),
                dwHighDateTime = (uint)((ulong)value >> 32),
            };
        }

        public static implicit operator FILETIME(TimeSpan value)
        {
            return value.Ticks;
        }

        public static implicit operator FILETIME(DateTime value)
        {
            return value.Ticks;
        }

        public static implicit operator long(FILETIME ft)
        {
            return (((long)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
        }

        public static implicit operator DateTime(FILETIME ft)
        {
            return DateTime.FromFileTime(ft);
        }

        public static implicit operator TimeSpan(FILETIME ft)
        {
            return TimeSpan.FromTicks(ft);
        }

        public override string ToString()
        {
            return DateTime.FromFileTime((long)this).ToString();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct FLASHWINFO
    {
        public uint cbSize;
        public HWND hwnd;
        public FlashWindowFlags dwFlags;
        public uint uCount;
        public uint dwTimeout;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct FORMATETC
    {
        public CLIPFORMAT cfFormat;
        public DVTARGETDEVICE* ptd;
        public DVASPECT dwAspect;
        public int lindex;
        public TYMED tymed;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct GESTURECONFIG
    {
        public GestureId dwID;
        public uint dwWant;
        public uint dwBlock;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct GESTUREINFO
    {
        public uint cbSize;
        public GestureFlags dwFlags;
        public GestureId dwID;
        public HWND hwndTarget;
        public POINTS ptsLocation;
        public uint dwInstanceID;
        public uint dwSequenceID;
        public ulong ullArguments;
        public uint cbExtraArgs;
    }

    /// <summary>
    /// A pointer to a GESTURENOTIFYSTRUCT is sent in the lParam of a WM_GESTURENOTIFY.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct GESTURENOTIFYSTRUCT
    {
        public uint cbSize;
        private uint dwFlags;  // Reserved for future use.
        public HWND hwndTarget;
        public POINTS ptsLocation;
        public GestureId dwInstanceID;
    }

    /// <summary>
    /// We can't use this anymore because the compiler complains about the Data4 field being incorrectly aligned.
    /// </summary>
    [Obsolete]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Size = 16)]
    public struct GUID
    {
        [FieldOffset(0)]
        public uint Data1;
        [FieldOffset(4)]
        public ushort Data2;
        [FieldOffset(6)]
        public ushort Data3;
        [FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Data4;

        public static implicit operator Guid(GUID guid)
        {
            return new Guid((int)guid.Data1, (short)guid.Data2, (short)guid.Data3, guid.Data4);
        }

        public static implicit operator GUID(Guid guid)
        {
            byte[] bytes = guid.ToByteArray();

            byte[] Data4bytes = new byte[8];
            Array.Copy(bytes, 8, Data4bytes, 0, 8);

            return new GUID
            {
                Data1 = BitConverter.ToUInt32(bytes, 0),
                Data2 = BitConverter.ToUInt16(bytes, 4),
                Data3 = BitConverter.ToUInt16(bytes, 6),
                Data4 = Data4bytes,
            };
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct HARDWAREINPUT
    {
        public uint uMsg;
        public short wParamL;
        public short wParamH;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{_handle}")]
    public struct HANDLE
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static readonly HANDLE NULL = new HANDLE(0);
        public static readonly HANDLE INVALID_HANDLE_VALUE = new HANDLE(-1);

        private unsafe HANDLE(int iPseudoHandle)
        {
            _handle = (void*)iPseudoHandle;
        }

        public unsafe bool IsNullOrInvalid
        {
            get
            {
                return (_handle == null || _handle == INVALID_HANDLE_VALUE._handle);
            }
        }

        public bool IsInheritable
        {
            get
            {
                HandleInformationFlags flags;
                if (!KERNEL32.GetHandleInformation(this, out flags))
                    throw new Win32Exception();
                return ((flags & HandleInformationFlags.HANDLE_FLAG_INHERIT) == HandleInformationFlags.HANDLE_FLAG_INHERIT);
            }
            set
            {
                if (!KERNEL32.SetHandleInformation(this, HandleInformationFlags.HANDLE_FLAG_INHERIT, value ? HandleInformationFlags.HANDLE_FLAG_INHERIT : 0))
                    throw new Win32Exception();
            }
        }

        public bool IsProtectedFromClose
        {
            get
            {
                HandleInformationFlags flags;
                if (!KERNEL32.GetHandleInformation(this, out flags))
                    throw new Win32Exception();
                return ((flags & HandleInformationFlags.HANDLE_FLAG_PROTECT_FROM_CLOSE) == HandleInformationFlags.HANDLE_FLAG_PROTECT_FROM_CLOSE);
            }
            set
            {
                if (!KERNEL32.SetHandleInformation(this, HandleInformationFlags.HANDLE_FLAG_PROTECT_FROM_CLOSE, value ? HandleInformationFlags.HANDLE_FLAG_PROTECT_FROM_CLOSE : 0))
                    throw new Win32Exception();
            }
        }

        public unsafe static bool operator ==(HANDLE h1, HANDLE h2)
        {
            return (h1._handle == h2._handle);
        }

        public unsafe static bool operator !=(HANDLE h1, HANDLE h2)
        {
            return (h1._handle != h2._handle);
        }

        public unsafe static implicit operator HANDLE(IntPtr handle)
        {
            return new HANDLE { _handle = (void*)handle };
        }

        public unsafe static implicit operator IntPtr(HANDLE handle)
        {
            return new IntPtr(handle._handle);
        }

        public unsafe override int GetHashCode()
        {
            return (int)_handle;
        }

        public unsafe override bool Equals(object obj)
        {
            return (obj is HANDLE) && ((HANDLE)obj)._handle == _handle;
        }
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HBITMAP
    {
        [FieldOffset(0)]
        internal unsafe void* _handle;

        public static readonly HBITMAP NULL = default(HBITMAP);

        public unsafe bool IsNull
        {
            get { return (_handle == null); }
        }
    }

    /// <summary>
    /// Handle to a device context.
    /// </summary>
    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HDC
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static readonly HDC NULL = default(HDC);
    }

    /// <summary>
    /// Handle to a desktop.
    /// </summary>
    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HDESK
    {
        [FieldOffset(0)]
        private unsafe void* _handle;
    }

    /// <summary>
    /// Handle to drag-and-drop information.
    /// </summary>
    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HDROP
    {
        [FieldOffset(0)]
        private IntPtr _handle;

        /// <summary>
        /// This is necessary because HDROP is received in the wParam of a WM_DROPFILES.
        /// </summary>
        public static implicit operator HDROP(UINT_PTR wParam)
        {
            return new HDROP { _handle = wParam };
        }
    }

    /// <summary>
    /// </summary>
    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HGESTUREINFO
    {
        [FieldOffset(0)]
        private IntPtr _handle;

        /// <summary>
        /// This is necessary because HGESTUREINFO is received in the lParam of a WM_GESTURE.
        /// </summary>
        public static implicit operator HGESTUREINFO(UINT_PTR lParam)
        {
            return new HGESTUREINFO { _handle = lParam };
        }
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HGLOBAL
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static HGLOBAL NULL = default(HGLOBAL);

        public bool IsNull
        {
            get { unsafe { return (_handle == null); } }
        }
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HICON
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static readonly HICON NULL = default(HICON);

        public unsafe bool IsNull
        {
            get { return (_handle == null); }
        }
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HINTERNET
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static HINTERNET NULL = default(HINTERNET);

        public bool IsNull
        {
            get { unsafe { return (_handle == null); } }
        }
    }

    /// <summary>
    /// All properties on this type are relative to the local process.
    /// </summary>
    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HINSTANCE
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static HINSTANCE NULL = default(HINSTANCE);

        public unsafe bool IsNull
        {
            get { return (_handle == null); }
        }

        public string ModulePath
        {
            get { return KERNEL32.GetModuleFileName(this); }
        }

        /// <summary>
        /// HINSTANCE is actually a pointer to the base address of the module in question.
        /// </summary>
        public unsafe static implicit operator void*(HINSTANCE hInstance)
        {
            return hInstance._handle;
        }

        public unsafe static implicit operator HINSTANCE(UINT_PTR ptr)
        {
            return new HINSTANCE { _handle = ptr };
        }

        public unsafe static implicit operator IntPtr(HINSTANCE hInstance)
        {
            return new IntPtr(hInstance._handle);
        }

        public unsafe static implicit operator UINT_PTR(HINSTANCE hInstance)
        {
            return new UINT_PTR(hInstance._handle);
        }
    }

    /// <summary>
    /// Handle to a menu.
    /// </summary>
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{_handle}")]
    public struct HMENU
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static readonly HMENU NULL = default(HMENU);

        public unsafe bool IsNull
        {
            get { return (_handle == null); }
        }
    }

    /// <summary>
    /// Handle to a monitor. All properties throw exceptions on failure.
    /// </summary>
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("DeviceName = {DeviceName}, Handle = {_handle}")]
    public struct HMONITOR
    {
        [FieldOffset(0)]
        private IntPtr _handle;

        public RECT TotalArea
        {
            get { return USER32.GetMonitorInfo(this).rcMonitor; }
        }

        public RECT WorkArea
        {
            get { return USER32.GetMonitorInfo(this).rcWork; }
        }

        public MONITORINFOF Flags
        {
            get { return USER32.GetMonitorInfo(this).dwFlags; }
        }

        public string DeviceName
        {
            get { return USER32.GetMonitorInfo(this).szDevice; }
        }

        public bool IsPrimary
        {
            get { return USER32.GetMonitorInfo(this).IsPrimary; }
        }

        public override string ToString()
        {
            return DeviceName;
        }
    }

    /// <summary>
    /// Handle to drag-and-drop information.
    /// </summary>
    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HRAWINPUT
    {
        [FieldOffset(0)]
        internal unsafe void* _handle;

        /// <summary>
        /// This is necessary because HRAWINPUT is received in the wParam of a WM_DROPFILES.
        /// </summary>
        public static implicit operator HRAWINPUT(UINT_PTR wParam)
        {
            return new HRAWINPUT { _handle = wParam };
        }
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct HRGN
    {
        [FieldOffset(0)]
        internal unsafe void* _handle;

        public static readonly HRGN NULL = default(HRGN);

        public unsafe bool IsNull
        {
            get { return (_handle == null); }
        }
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{_handle}")]
    public struct HTOUCHINPUT
    {
        [FieldOffset(0)]
        internal unsafe void* _handle;

        /// <summary>
        /// This is necessary because HTOUCHINPUT is received in the lParam of a WM_TOUCH.
        /// </summary>
        public static implicit operator HTOUCHINPUT(IntPtr lParam)
        {
            unsafe { return new HTOUCHINPUT { _handle = (void*)lParam }; }
        }
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{_handle}")]
    public struct HWINEVENTHOOK
    {
        [FieldOffset(0)]
        private IntPtr _handle;

        public static readonly HWINEVENTHOOK NULL = default(HWINEVENTHOOK);

        public bool IsNull
        {
            get { return (_handle == IntPtr.Zero); }
        }
    }

    /// <summary>
    /// Handle to a window station.
    /// </summary>
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{_handle}")]
    public struct HWINSTA
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public unsafe static implicit operator IntPtr(HWINSTA hWinSta)
        {
            return new IntPtr(hWinSta._handle);
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct ICMP_ECHO_REPLY
    {
        public IN_ADDR Address;
        public IP_STATUS Status;
        public uint RoundTripTime;
        public ushort DataSize;
        public ushort Reserved;
        public UINT_PTR Data;
        public IP_OPTION_INFORMATION Options;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct ImgDelayDescr
    {
        public uint grAttrs;        // attributes
        public uint rvaDLLName;     // RVA to dll name
        public uint rvaHmod;        // RVA of module handle
        public uint rvaIAT;         // RVA of the IAT
        public uint rvaINT;         // RVA of the INT
        public uint rvaBoundIAT;    // RVA of the optional bound IAT
        public uint rvaUnloadIAT;   // RVA of optional copy of original IAT
        public uint dwTimeStamp;    // 0 if not bound, O.W. date/time stamp of DLL bound to (Old BIND)
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct IMAGE_EXPORT_DIRECTORY
    {
        public uint Characteristics;
        public uint TimeDateStamp;
        public ushort MajorVersion;
        public ushort MinorVersion;
        public uint Name;
        /// <summary>
        /// This field contains the starting ordinal value to be used for this executable's exports.
        /// Normally, this value is 1, but it's not required to be so.
        /// When looking up an export by ordinal, the value of this field is subtracted from the ordinal,
        /// with the result used as a zero-based index into the Export Address Table (EAT).
        /// </summary>
        public uint Base;
        public uint NumberOfFunctions;
        public uint NumberOfNames;
        public uint AddressOfFunctions;     // RVA from base of image
        public uint AddressOfNames;         // RVA from base of image

        /// <summary>
        /// An RVA from base of image, to an array of RVAs.
        /// </summary>
        public uint AddressOfNameOrdinals;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{ManagedName}")]
    public unsafe struct IMAGE_IMPORT_BY_NAME
    {
        [FieldOffset(0)]
        public ushort Hint;
        [FieldOffset(2)]
        public fixed sbyte Name[1];

        public string ManagedName
        {
            get
            {
                fixed (sbyte* pszName = Name)
                    return Marshal.PtrToStringAnsi((IntPtr)pszName);
            }
        }
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct IMAGE_IMPORT_DESCRIPTOR
    {
        [FieldOffset(0)]
        public IMAGE_SCN Characteristics;            // 0 for terminating null import descriptor
        [FieldOffset(0)]
        public uint OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)

        [FieldOffset(4)]
        public uint TimeDateStamp;
        [FieldOffset(8)]
        public uint ForwarderChain;
        [FieldOffset(12)]
        public uint Name;
        [FieldOffset(16)]
        public uint FirstThunk;

        public bool IsEmpty
        {
            get { return (OriginalFirstThunk == 0 && TimeDateStamp == 0 && ForwarderChain == 0 && Name == 0 && FirstThunk == 0); }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct IMAGE_THUNK_DATA
    {
        public UINT_PTR ForwarderString;      // PBYTE 
        public UINT_PTR Function;             // PDWORD
        public UINT_PTR Ordinal;
        public UINT_PTR AddressOfData;        // PIMAGE_IMPORT_BY_NAME
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{Name}")]
    public struct IMAGE_SECTION_HEADER
    {
        public const int IMAGE_SIZEOF_SHORT_NAME = 8;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = IMAGE_SIZEOF_SHORT_NAME)]
        public string Name;

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
        public struct Misc
        {
            [FieldOffset(0)]
            public uint PhysicalAddress;
            [FieldOffset(0)]
            public uint VirtualSize;
        }

        public uint VirtualAddress;
        public uint SizeOfRawData;
        public uint PointerToRawData;
        public uint PointerToRelocations;
        public uint PointerToLinenumbers;
        public ushort NumberOfRelocations;
        public ushort NumberOfLinenumbers;
        public IMAGE_SCN Characteristics;
    }

    /// <summary>
    /// Represents an IPv4 address in network byte order.
    /// </summary>
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Size = 4)]
    public struct IN_ADDR
    {
        public static readonly IN_ADDR INADDR_ANY = new IN_ADDR { S_addr = 0 };
        public static readonly IN_ADDR INADDR_LOOPBACK = new IN_ADDR { S_addr = 0x7f000001 };
        public static readonly IN_ADDR INADDR_BROADCAST = new IN_ADDR { S_addr = 0xffffffff };
        public static readonly IN_ADDR INADDR_NONE = new IN_ADDR { S_addr = 0xffffffff };

        public static IN_ADDR Parse(string strAddress)
        {
            return new IN_ADDR { S_addr = WS2_32.inet_addr(strAddress) };
        }

        [FieldOffset(0)]
        public byte s_b1;
        [FieldOffset(1)]
        public byte s_b2;
        [FieldOffset(2)]
        public byte s_b3;
        [FieldOffset(3)]
        public byte s_b4;
        [FieldOffset(0)]
        public ushort s_w1;
        [FieldOffset(2)]
        public ushort s_w2;
        [FieldOffset(0)]
        public uint S_addr;
    }

    /// <summary>
    /// Represents an IPv6 address in network byte order.
    /// </summary>
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Size = 16)]
    public unsafe struct IN6_ADDR
    {
        [FieldOffset(0)]
        public fixed byte Byte[16];
        [FieldOffset(0)]
        public fixed ushort Word[8];
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("{type}")]
    public struct INPUT
    {
        [FieldOffset(0)]
        public InputType type;
        [FieldOffset(4)]
        public MOUSEINPUT mi;
        [FieldOffset(4)]
        public KEYBDINPUT ki;
        [FieldOffset(4)]
        public HARDWAREINPUT hi;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct IO_COUNTERS
    {
        public ulong ReadOperationCount;
        public ulong WriteOperationCount;
        public ulong OtherOperationCount;
        public ulong ReadTransferCount;
        public ulong WriteTransferCount;
        public ulong OtherTransferCount;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct IP_OPTION_INFORMATION
    {
        public byte Ttl;
        public byte Tos;
        public IpOptionInformationFlags Flags;
        public byte OptionsSize;
        public UINT_PTR OptionsData;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct ITEMIDLIST
    {
        public SHITEMID mkid;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_BKINFO
    {
        public JET_LGPOS lgposMark;

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
        public struct _DUMMYUNIONNAME
        {
            [FieldOffset(0)]
            public JET_LOGTIME logtimeMark;
            [FieldOffset(0)]
            public JET_BKLOGTIME bklogtimeMark;
        }
        public _DUMMYUNIONNAME DUMMYUNIONNAME;

        public uint genLow;
        public uint genHigh;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_BKLOGTIME
    {
        public byte bSeconds;
        public byte bMinutes;
        public byte bHours;
        public byte bDay;
        public byte bMonth;

        private byte bFiller1;
        private byte bFiller2;

        public bool fTimeIsUTC
        {
            get { return ((bFiller1 & 1) == 1); }
        }

        public bool fOSSnapshot
        {
            get { return ((bFiller2 & 1) == 1); }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_COLUMNBASE
    {
        public uint cbStruct;
        public JET_COLUMNID columnid;
        public JET_COLTYP coltyp;
        public ushort wCountry;
        public ushort langid;
        public ushort cp;
        public ushort wFiller;
        public uint cbMax;
        public JET_GRBIT grbit;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szBaseTableName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szBaseColumnName;
    }

    [DebuggerDisplay("{szColumnName} as {coltyp}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_COLUMNCREATE
    {
        public uint cbStruct;
        [MarshalAs(UnmanagedType.LPStr)]
        public string szColumnName;
        public JET_COLTYP coltyp;
        public uint cbMax;
        public JET_GRBIT grbit;
        public UINT_PTR pvDefault;
        public uint cbDefault;
        public uint cp;
        public JET_COLUMNID columnid;
        public JET_ERR err;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_COLUMNDEF
    {
        public uint cbStruct;
        /// <summary>Must be set to zero when calling an ESENT function.</summary>
        public JET_COLUMNID columnid;
        public JET_COLTYP coltyp;
        /// <summary>Obsolete. Must be set to zero.</summary>
        [Obsolete]
        private ushort wCountry;
        /// <summary>Obsolete. Must be set to zero.</summary>
        [Obsolete]
        private LANGID langid;
        /// <summary>Code page for string data. Use the CodePage enum for a list of preferred values.</summary>
        public ushort cp;
        /// <summary>Reserved. Must be set to zero.</summary>
        private ushort wCollate;
        public uint cbMax;
        public JET_GRBIT grbit;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_CONDITIONALCOLUMN
    {
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_DBINFOMISC
    {
        public uint ulVersion;
        public uint ulUpdate;
        public JET_SIGNATURE signDb;
        public JetDbState dbstate;
        public JET_LGPOS lgposConsistent;
        public JET_LOGTIME logtimeConsistent;
        public JET_LOGTIME logtimeAttach;
        public JET_LGPOS lgposAttach;
        public JET_LOGTIME logtimeDetach;
        public JET_LGPOS lgposDetach;
        public JET_SIGNATURE signLog;
        public JET_BKINFO bkinfoFullPrev;
        public JET_BKINFO bkinfoIncPrev;
        public JET_BKINFO bkinfoFullCur;
        public uint fShadowingDisabled;
        public uint fUpgradeDb;
        public uint dwMajorVersion;
        public uint dwMinorVersion;
        public uint dwBuildNumber;
        public int lSPNumber;
        public uint cbPageSize;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_DBINFOUPGRADE
    {
        public uint cbStruct;
        public uint cbFilesizeLow;
        public uint cbFilesizeHigh;
        public uint cbFreeSpaceRequiredLow;
        public uint cbFreeSpaceRequiredHigh;
        public uint csecToUpgrade;
        public JetDbInfoUpgradeFlags ulFlags;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_ENUMCOLUMNID
    {
        public JET_COLUMNID columnid;
        public uint ctagSequence;
        /// <summary>Pointer to an array of uints.</summary>
        public UINT_PTR rgtagSequence;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_ENUMCOLUMNVALUE
    {
        public uint itagSequence;
        public JET_ERR err;
        public uint cbData;
        public UINT_PTR pvData;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_HANDLE
    {
        private unsafe void* _handle;
    }

    /// <summary>
    /// This struct is a P/Invoke MESS.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_INDEXCREATE
    {
        public uint cbStruct;
        [MarshalAs(UnmanagedType.LPStr)]
        public string szIndexName;
        /// <summary>Double-zero terminated.</summary>
        [MarshalAs(UnmanagedType.LPStr)]
        public string szKey;
        /// <summary>
        /// This is a count of bytes in the key string, including all null terminators.
        /// Do not confuse this with a count of characters as the documentation may indicate,
        /// or you will get access violations.
        /// </summary>
        public uint cbKey;
        public JET_GRBIT grbit;
        public uint ulDensity;

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
        public struct union1
        {
            [FieldOffset(0)]
            public LCID lcid;
            [FieldOffset(0)]
            public UINT_PTR pidxunicode; //JET_UNICODEINDEX*
        }
        public union1 _union1;

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
        public struct union2
        {
            [FieldOffset(0)]
            public uint cbVarSegMac;
            [FieldOffset(0)]
            public UINT_PTR ptuplelimits; //JET_TUPLELIMITS*
        }
        public union2 _union2;

        /// <summary>Array of JET_CONDITIONALCOLUMN*</summary>
        public UINT_PTR rgconditionalcolumn;
        public uint cConditionalColumn;
        public JET_ERR err;

        /// NOTE: This was introduced after the JET_ERR variable, in Windows Vista.
        /// It would complicate things tremendously to keep it in for now if we want XP compatibility.
        /// The alternative is separate versions but I'd rather not.
        //public uint cbKeyMost;
    }

    /// <summary>
    /// This struct is generally intended to be manipulated as an opaque handle.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_INDEXID
    {
        public uint cbStruct;

        /// This data is meant to be hidden from the caller.
        /// We can't declare a byte array because the pointer-sized value adds volatility.
        /// public rgbIndexId[sizeof(JET_API_PTR)+sizeof(uint)+sizeof(uint)];
        private UINT_PTR rgbIndexId_placeholder1;
        private uint rgbIndexId_placeholder2;
        private uint rgbIndexId_placeholder3;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_INDEXLIST
    {
        public uint cbStruct;
        public JET_TABLEID tableid;
        public uint cRecord;
        public JET_COLUMNID columnidindexname;
        public JET_COLUMNID columnidgrbitIndex;
        public JET_COLUMNID columnidcKey;
        public JET_COLUMNID columnidcEntry;
        public JET_COLUMNID columnidcPage;
        public JET_COLUMNID columnidcColumn;
        public JET_COLUMNID columnidiColumn;
        public JET_COLUMNID columnidcolumnid;
        public JET_COLUMNID columnidcoltyp;
        public JET_COLUMNID columnidCountry;
        public JET_COLUMNID columnidLangid;
        public JET_COLUMNID columnidCp;
        public JET_COLUMNID columnidCollate;
        public JET_COLUMNID columnidgrbitColumn;
        public JET_COLUMNID columnidcolumnname;
        public JET_COLUMNID columnidLCMapFlags;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_INDEXRANGE
    {
        public uint cbStruct;
        public JET_TABLEID tableid;
        public JET_GRBIT grbit;
    }

    public struct JET_INSTANCE
    {
        public unsafe static readonly JET_INSTANCE JET_instanceNil = new JET_INSTANCE { _handle = (void*)(-1) };
        public unsafe static readonly JET_INSTANCE NULL = new JET_INSTANCE { _handle = null };
        private unsafe void* _handle;
        public unsafe bool IsNull { get { return (_handle == (void*)(-1) || _handle == null); } }
    }

    public static class JET_INSTANCE_INFO
    {
        [DebuggerDisplay("{szInstanceName} {cDatabases} database(s)")]
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct Raw
        {
            public JET_INSTANCE hInstanceId;
            [MarshalAs(UnmanagedType.LPStr)]
            public string szInstanceName;
            /// <summary>
            /// The number of databases that are attached to the database instance.
            /// cDatabases also holds the size of the arrays of strings that are returned in
            /// szDatabaseFileName, szDatabaseDisplayName, and szDatabaseSLVFileName.
            /// </summary>
            public UINT_PTR cDatabases;
            /// <summary>Pointer to an array of pointers to strings.</summary>
            public UINT_PTR szDatabaseFileName;
            /// <summary>Pointer to an array of pointers to strings.</summary>
            public UINT_PTR szDatabaseDisplayName;
            /// <summary>Pointer to an array of pointers to strings.</summary>
            public UINT_PTR szDatabaseSLVFileName;
        }

        [DebuggerDisplay("{szInstanceName} {cDatabases} database(s)")]
        public struct Managed
        {
            public JET_INSTANCE hInstanceId;
            public string szInstanceName;
            public int cDatabases;
            public string[] szDatabaseFileName;
            public string[] szDatabaseDisplayName;
            public string[] szDatabaseSLVFileName;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_LGPOS
    {
        public ushort ib; // must be the last so that lgpos can
        public ushort isec; // index of disksec starting logsec
        public long lGeneration; // generation of logsec
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_LOGINFO
    {
        public uint cbSize;
        public uint ulGenLow;
        public uint ulGenHigh;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.JET_BASE_NAME_LENGTH + 1)]
        public string szBaseName;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_LOGTIME
    {
        public byte bSeconds; // 0 - 59
        public byte bMinutes; // 0 - 59
        public byte bHours; // 0 - 23
        public byte bDay; // 1 - 31
        public byte bMonth; // 1 - 12
        public byte bYear; // current year - 1900
        public byte bFiller1;
        public byte bFiller2;

        public bool fTimeIsUTC
        {
            get { return ((bFiller1 & 1) == 1); }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_LS
    {
        public unsafe static readonly JET_LS JET_LSNil = new JET_LS { _handle = (void*)(-1) };
        private unsafe void* _handle;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_OBJECTINFO
    {
        public uint cbStruct;
        public JET_OBJTYP objtyp;
        [Obsolete]
        private double dtCreate;
        [Obsolete]
        private double dtUpdate;
        public JET_GRBIT grbit;
        public JET_GRBIT flags;
        public uint cRecord;
        public uint cPage;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_OPENTEMPORARYTABLE
    {
        public uint cbStruct;
        public UINT_PTR prgcolumndef; //JET_COLUMNDEF*
        public uint ccolumn;
        public UINT_PTR pidxunicode; //JET_UNICODEINDEX*
        public JET_GRBIT grbit;
        public UINT_PTR prgcolumnid; //JET_COLUMNID*
        public uint cbKeyMost;
        public uint cbVarSegMac;
        public JET_TABLEID tableid;
    }

    /// <summary>
    /// Snapshot Session Identifier
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_OSSNAPID
    {
        private unsafe void* _handle;
        public unsafe bool IsNull { get { return (_handle == null); } }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RECORDLIST
    {
        public uint cbStruct;
        public JET_TABLEID tableid;
        public uint cRecord;
        public JET_COLUMNID columnidBookmark;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RECPOS
    {
        public uint cbStruct;
        public uint centriesLT;
        public uint centriesInRange;
        public uint centriesTotal;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RECSIZE
    {
        public ulong cbData;
        public ulong cbLongValueData;
        public ulong cbOverhead;
        public ulong cbLongValueOverhead;
        public ulong cNonTaggedColumns;
        public ulong cTaggedColumns;
        public ulong cLongValues;
        public ulong cMultiValues;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RETINFO
    {
        public uint cbStruct;
        public uint ibLongValue;
        public uint itagSequence;
        public JET_COLUMNID columnidNextTagged;
    }

    [DebuggerDisplay("({err}) cbData = {cbData}, cbActual = {cbActual}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RETRIEVECOLUMN
    {
        public JET_COLUMNID columnid;
        public UINT_PTR pvData;
        public uint cbData;
        public uint cbActual;
        public JET_GRBIT grbit;
        public uint ibLongValue;
        public uint itagSequence;
        public JET_COLUMNID columnidNextTagged;
        public JET_ERR err;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RSTINFO
    {
        public uint cbStruct;
        /// <summary>Pointer to an array of JET_RSTMAP.</summary>
        public UINT_PTR rgrstmap;
        /// <summary>Count of array entries in the rgrstmap.</summary>
        public long crstmap;
        public JET_LGPOS lgposStop;
        public JET_LOGTIME logtimeStop;
        public JET_PFNSTATUS pfnStatus;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_RSTMAP
    {
        [MarshalAs(UnmanagedType.LPStr)]
        public string szDatabaseName;
        [MarshalAs(UnmanagedType.LPStr)]
        public string szNewDatabaseName;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_SESID
    {
        public unsafe static readonly JET_SESID JET_sesidNil = new JET_SESID { _handle = (void*)(-1) };
        public unsafe static readonly JET_SESID NULL = new JET_SESID { _handle = null };
        private unsafe void* _handle;
        public unsafe bool IsNull { get { return (_handle == (void*)(-1) || _handle == null); } }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_SETCOLUMN
    {
        public JET_COLUMNID columnid;
        public UINT_PTR pvData;
        public uint cbData;
        public JET_GRBIT grbit;
        public uint ibLongValue;
        public uint itagSequence;
        public JET_ERR err;
    }

    public struct JET_SETINFO
    {
        public uint cbStruct;
        public uint ibLongValue;
        public uint itagSequence;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_SETSYSPARAM
    {
        public uint paramid;
        public INT_PTR lParam;
        [MarshalAs(UnmanagedType.LPStr)]
        public string sz;
        public JET_ERR err;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_SIGNATURE
    {
        public uint ulRandom;
        public JET_LOGTIME logtimeCreate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.JET_MAX_COMPUTERNAME_LENGTH + 1)]
        public string szComputerName;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_SNPROG
    {
        public uint cbStruct;
        public uint cunitDone;
        public uint cunitTotal;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_SPACEHINTS
    {
        public uint cbStruct;    // size of this structure 
        public uint ulInitialDensity; // density at (append) layout.
        public uint cbInitial;   // initial size (in bytes).
        /// <summary>
        /// Combination of one or more flags from
        ///  JET_bitSpaceHints* flags
        ///  JET_bitCreateHints* flags
        ///  JET_bitRetrieveHints* flags
        ///  JET_bitUpdateHints* flags
        ///  JET_bitDeleteHints* flags
        /// </summary>
        public JET_GRBIT grbit;
        public uint ulMaintDensity;  // density to maintain at.
        public uint ulGrowth;   // percent growth from: last growth or initial size (possibly rounded to nearest native JET allocation size).
        public uint cbMinExtent;  // This overrides ulGrowth if too small.
        public uint cbMaxExtent;  // This caps ulGrowth.
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_TABLECREATE
    {
        public uint cbStruct;
        [MarshalAs(UnmanagedType.LPStr)]
        string szTableName;
        [MarshalAs(UnmanagedType.LPStr)]
        string szTemplateTableName;
        public uint ulPages;
        public uint ulDensity;
        /// <summary>Pointer to an array of JET_COLUMNCREATE.</summary>
        public UINT_PTR rgcolumncreate;
        public uint cColumns;
        /// <summary>Pointer to an array of JET_INDEXCREATE.</summary>
        public UINT_PTR rgindexcreate;
        public uint cIndexes;
        public JET_GRBIT grbit;
        public JET_TABLEID tableid;
        public uint cCreated;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_TABLECREATE2
    {
        public uint cbStruct;
        [MarshalAs(UnmanagedType.LPStr)]
        public string szTableName;
        [MarshalAs(UnmanagedType.LPStr)]
        public string szTemplateTableName;
        public uint ulPages;
        public uint ulDensity;
        /// <summary>Pointer to an array of JET_COLUMNCREATE.</summary>
        public UINT_PTR rgcolumncreate;
        public uint cColumns;
        /// <summary>Pointer to an array of JET_INDEXCREATE.</summary>
        public UINT_PTR rgindexcreate;
        public uint cIndexes;
        [MarshalAs(UnmanagedType.LPStr)]
        public string szCallback;
        public JET_CBTYP cbtyp;
        public JET_GRBIT grbit;
        public JET_TABLEID tableid;
        public uint cCreated;
    }

    /// <summary>
    /// This was introduced in Windows 7, which means it always has a Unicode version.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct JET_TABLECREATE3
    {
        public uint cbStruct;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szTableName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szTemplateTableName;
        public uint ulPages;
        public uint ulDensity;
        /// <summary>Pointer to an array of JET_COLUMNCREATE.</summary>
        public UINT_PTR rgcolumncreate;
        public uint cColumns;
        /// <summary>Pointer to an array of JET_INDEXCREATE2.</summary>
        public UINT_PTR rgindexcreate;
        public uint cIndexes;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szCallback;
        public JET_CBTYP cbtyp;
        public JET_GRBIT grbit;
        /// <summary>Pointer to a JET_SPACEHINTS.</summary>
        public UINT_PTR pSeqSpacehints;
        /// <summary>Pointer to a JET_SPACEHINTS.</summary>
        public UINT_PTR pLVSpacehints;
        public uint cbSeparateLV;
        public JET_TABLEID tableid;
        public uint cCreated;
    }

    /// <summary>
    /// Table cursor.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_TABLEID
    {
        public unsafe static readonly JET_TABLEID JET_tableidNil = new JET_TABLEID { _handle = (void*)(-1) };
        private unsafe void* _handle;
        public unsafe bool IsNull { get { return (_handle == (void*)(-1)); } }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_THREADSTATS
    {
        public uint cbStruct;
        public uint cPageReferenced;
        public uint cPageRead;
        public uint cPagePreread;
        public uint cPageDirtied;
        public uint cPageRedirtied;
        public uint cLogRecord;
        public uint cbLogRecord;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_TUPLELIMITS
    {
        public uint chLengthMin;
        public uint chLengthMax;
        public uint chToIndexMax;
        public uint cchIncrement;
        public uint ichStart;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct JET_UNICODEINDEX
    {
        public uint lcid;
        public LocaleMappingFlags dwMapFlags;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct KEYBDINPUT
    {
        public ushort wVK;
        public ushort wScan;
        public KeyboardEventFlags dwFlags;
        public uint time;
        public UINT_PTR dwExtraInfo;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct LARGE_INTEGER
    {
        [FieldOffset(0)]
        public uint LowPart;
        [FieldOffset(4)]
        public int HighPart;
        [FieldOffset(0)]
        public long QuadPart;

        public static implicit operator LARGE_INTEGER(long oldvalue)
        {
            return new LARGE_INTEGER { QuadPart = oldvalue };
        }

        public static implicit operator long(LARGE_INTEGER oldvalue)
        {
            return oldvalue.QuadPart;
        }

        public override string ToString()
        {
            return QuadPart.ToString();
        }

        public string ToString(string strFormat)
        {
            return QuadPart.ToString(strFormat);
        }
    }

    [DebuggerDisplay("{dwTime}")]
    [StructLayout(LayoutKind.Sequential)]
    public struct LASTINPUTINFO
    {
        public uint cbSize;
        public uint dwTime;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MARGINS
    {
        public int Left;
        public int Right;
        public int Top;
        public int Bottom;

        public static implicit operator MARGINS(System.Windows.Thickness t)
        {
            MARGINS m = new MARGINS
            {
                Left = (int)t.Left,
                Right = (int)t.Right,
                Top = (int)t.Top,
                Bottom = (int)t.Bottom,
            };
            return m;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MEMORY_BASIC_INFORMATION
    {
        public UINT_PTR BaseAddress;
        public UINT_PTR AllocationBase;
        public MemoryFlags AllocationProtect;
        public UINT_PTR RegionSize;
        public MemoryFlags State;
        public MemoryFlags Protect;
        public MemoryFlags Type;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MEMORYSTATUSEX
    {
        public uint dwLength;
        public uint dwMemoryLoad;
        public ulong ullTotalPhys;
        public ulong ullAvailPhys;
        public ulong ullTotalPageFile;
        public ulong ullAvailPageFile;
        public ulong ullTotalVirtual;
        public ulong ullAvailVirtual;
        public ulong ullAvailExtendedVirtual;
    }

    [DebuggerDisplay("{szPname}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MIDIOUTCAPS
    {
        public ushort wMid;                  /* manufacturer ID */
        public ushort wPid;                  /* product ID */
        public uint vDriverVersion;      /* version of the driver */
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAXPNAMELEN)]
        public string szPname; /* product name (NULL terminated string) */
        public ushort wTechnology;           /* type of device */
        public ushort wVoices;               /* # of voices (internal synth only) */
        public ushort wNotes;                /* max # of notes (internal synth only) */
        public ushort wChannelMask;          /* channels used (internal synth only) */
        public uint dwSupport;             /* functionality supported by driver */
    }

    [DebuggerDisplay("{szExeFile}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MODULEENTRY32
    {
        public uint dwSize;
        public uint th32ModuleID;
        public uint th32ProcessID;
        public uint GlblcntUsage;
        public uint ProccntUsage;
        public UINT_PTR modBaseAddr;
        public uint modBaseSize;
        public HINSTANCE hModule;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_MODULE_NAME32 + 1)]
        public string szModule;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_PATH)]
        public string szExeFile;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MOF_FIELD
    {
        public ulong DataPtr;
        public uint Length;
        public uint DataType;
    }

    [DebuggerDisplay("rcMonitor = {rcMonitor}, rcWork = {rcWork}, dwFlags = {dwFlags}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MONITORINFO
    {
        public uint cbSize;
        public RECT rcMonitor;
        public RECT rcWork;
        public MONITORINFOF dwFlags;

        public bool IsPrimary
        {
            get { return ((dwFlags & MONITORINFOF.MONITORINFOF_PRIMARY) == MONITORINFOF.MONITORINFOF_PRIMARY); }
        }
    }

    [DebuggerDisplay("szDevice = {szDevice}, rcMonitor = {rcMonitor}, rcWork = {rcWork}, dwFlags = {dwFlags}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MONITORINFOEX
    {
        public uint cbSize;
        public RECT rcMonitor;
        public RECT rcWork;
        public MONITORINFOF dwFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.CCHDEVICENAME)]
        public string szDevice;

        public bool IsPrimary
        {
            get { return ((dwFlags & MONITORINFOF.MONITORINFOF_PRIMARY) == MONITORINFOF.MONITORINFOF_PRIMARY); }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MOUSEINPUT
    {
        public int dx;
        public int dy;
        public uint mouseData;
        public MouseEventFlags dwFlags;
        public uint time;
        public UINT_PTR dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MSG
    {
        public HWND hwnd;
        public WindowMessageId message;
        public UINT_PTR wParam;
        public INT_PTR lParam;
        public uint time;
        public POINT pt;

        public MSG(
            HWND new_hwnd = default(HWND),
            WindowMessageId new_message = WindowMessageId.WM_NULL,
            UINT_PTR new_wParam = default(UINT_PTR),
            INT_PTR new_lParam = default(INT_PTR),
            uint new_time = 0,
            POINT new_pt = default(POINT))
        {
            hwnd = new_hwnd;
            message = new_message;
            wParam = new_wParam;
            lParam = new_lParam;
            time = new_time;
            pt = new_pt;
            return;
        }

        public TimeSpan Time
        {
            get { return TimeSpan.FromMilliseconds(time); }
        }

        public bool Post(HWND? hTargetOverride = null)
        {
            return USER32.PostMessage(hTargetOverride ?? hwnd, message, wParam, lParam);
        }

        public INT_PTR Send(HWND? hTargetOverride = null)
        {
            return USER32.SendMessage(hTargetOverride ?? hwnd, message, wParam, lParam);
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct MULTI_QI
    {
        /// <summary>Pointer to a Guid.</summary>
        [MarshalAs(UnmanagedType.LPStruct)]
        public Guid pIID;
        public IUnknown pItf;
        public HRESULT hr;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct NLSVERSIONINFO
    {
        public uint dwNLSVersionInfoSize;     // 12 bytes
        public uint dwNLSVersion;
        public uint dwDefinedVersion;
    }

    /// <summary>
    /// This is to be deprecated, please use the NLSVERSIONINFO structure above in the future.
    /// The difference is that the effective ID is more robust.
    /// </summary>
    [Obsolete]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct NLSVERSIONINFOEX
    {
        public uint dwNLSVersionInfoSize;     // sizeof(NLSVERSIONINFOEX) == 32 bytes
        public uint dwNLSVersion;
        public uint dwDefinedVersion;
        public uint dwEffectiveId;            // Use NLSVERSIONINFO instead
        [MarshalAs(UnmanagedType.Struct)]
        public Guid guidCustomVersion;
    }

    /// <summary>
    /// http://code.google.com/p/reactos-mirror/source/browse/trunk/reactos/dll/win32/shell32/undocshell.h?spec=svn51127&r=51127
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("lpFile = {lpFile}, lpDirectory = {lpDirectory}")]
    public struct NM_RUNFILEDLG
    {
        public NMHDR hdr;
        //[MarshalAs(UnmanagedType.LPWStr)]
        //public string lpFile;
        //[MarshalAs(UnmanagedType.LPWStr)]
        //public string lpDirectory;
        public UINT_PTR lpFile;
        public UINT_PTR lpDirectory;
        public ShowWindowCommand nShow;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("hwndFrom = {hwndFrom}, idFrom = {idFrom}, code = {code}")]
    public struct NMHDR
    {
        public HWND hwndFrom;
        public UINT_PTR idFrom;
        public uint code;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct NOTIFYICONIDENTIFIER
    {
        public uint cbSize;
        public HWND hWnd;
        public uint uID;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid guidItem;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OBJECT_ATTRIBUTES
    {
        public uint Length;
        public HANDLE RootDirectory;
        /// <summary>Pointer to a UNICODE_STRING.</summary>
        public UINT_PTR ObjectName;
        public ObjectAttributeFlags Attributes;
        public UINT_PTR SecurityDescriptor;
        public UINT_PTR SecurityQualityOfService;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OBJECT_DIRECTORY_INFORMATION
    {
        public UNICODE_STRING Name;
        public UNICODE_STRING TypeName;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OBJECT_NAME_INFORMATION
    {
        public UNICODE_STRING Name;
    }

    [DebuggerDisplay("{szCSDVersion}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OSVERSIONINFOEX
    {
        public uint dwOSVersionInfoSize;
        public uint dwMajorVersion;
        public uint dwMinorVersion;
        public uint dwBuildNumber;
        public uint dwPlatformId;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string szCSDVersion;
        public ushort wServicePackMajor;
        public ushort wServicePackMinor;
        public OSVersionSuiteMask wSuiteMask;
        public OSVersionProductType wProductType;
        public byte wReserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OVERLAPPED
    {
        public UINT_PTR Internal;
        public UINT_PTR InternalHigh;
        /*union {
          struct {
            public uint Offset;
            public uint OffsetHigh;
          };*/
        public UINT_PTR Pointer;
        public HANDLE hEvent;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct OVERLAPPED_ENTRY
    {
        public UINT_PTR lpCompletionKey;
        public NativeOverlapped lpOverlapped; /// This is supposed to be an address; may need to be an IntPtr.
        public UINT_PTR Internal;
        public uint dwNumberOfBytesTransferred;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct PDH_BROWSE_DLG_CONFIG
    {
        [Flags]
        private enum BitFieldMasks : uint
        {
            bIncludeInstanceIndex = 0x00000001,
            bSingleCounterPerAdd = 0x00000002,
            bSingleCounterPerDialog = 0x00000004,
            bLocalCountersOnly = 0x00000008,
            bWildCardInstances = 0x00000010,
            bHideDetailBox = 0x00000020,
            bInitializePath = 0x00000040,
            bDisableMachineSelection = 0x00000080,
            bIncludeCostlyObjects = 0x00000100,
            bShowObjectBrowser = 0x00000200,
            bReserved = 0xFFFFFE00,
        }

        /// <summary>
        /// This is implemented in C++ as a bitfield, and we can never assume bitfields are only going to be flags.
        /// </summary>
        private BitFieldMasks _flags;

        public bool bIncludeInstanceIndex
        {
            get { return ((_flags & BitFieldMasks.bIncludeInstanceIndex) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bIncludeInstanceIndex) : (_flags & ~BitFieldMasks.bIncludeInstanceIndex); }
        }

        public bool bSingleCounterPerAdd
        {
            get { return ((_flags & BitFieldMasks.bSingleCounterPerAdd) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bSingleCounterPerAdd) : (_flags & ~BitFieldMasks.bSingleCounterPerAdd); }
        }

        public bool bSingleCounterPerDialog
        {
            get { return ((_flags & BitFieldMasks.bSingleCounterPerDialog) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bSingleCounterPerDialog) : (_flags & ~BitFieldMasks.bSingleCounterPerDialog); }
        }

        public bool bLocalCountersOnly
        {
            get { return ((_flags & BitFieldMasks.bLocalCountersOnly) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bLocalCountersOnly) : (_flags & ~BitFieldMasks.bLocalCountersOnly); }
        }

        public bool bWildCardInstances
        {
            get { return ((_flags & BitFieldMasks.bWildCardInstances) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bWildCardInstances) : (_flags & ~BitFieldMasks.bWildCardInstances); }
        }

        public bool bHideDetailBox
        {
            get { return ((_flags & BitFieldMasks.bHideDetailBox) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bHideDetailBox) : (_flags & ~BitFieldMasks.bHideDetailBox); }
        }

        public bool bInitializePath
        {
            get { return ((_flags & BitFieldMasks.bInitializePath) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bInitializePath) : (_flags & ~BitFieldMasks.bInitializePath); }
        }

        public bool bDisableMachineSelection
        {
            get { return ((_flags & BitFieldMasks.bDisableMachineSelection) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bDisableMachineSelection) : (_flags & ~BitFieldMasks.bDisableMachineSelection); }
        }

        public bool bIncludeCostlyObjects
        {
            get { return ((_flags & BitFieldMasks.bIncludeCostlyObjects) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bIncludeCostlyObjects) : (_flags & ~BitFieldMasks.bIncludeCostlyObjects); }
        }

        public bool bShowObjectBrowser
        {
            get { return ((_flags & BitFieldMasks.bShowObjectBrowser) != 0); }
            set { _flags = value ? (_flags | BitFieldMasks.bShowObjectBrowser) : (_flags & ~BitFieldMasks.bShowObjectBrowser); }
        }

        public HWND hWndOwner;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szDataSource;
        public UINT_PTR szReturnPathBuffer;
        public uint cchReturnPathLength;
        public CounterPathCallBack pCallBack;
        public UINT_PTR dwCallBackArg;
        public PDH_STATUS CallBackStatus;
        public PerformanceCounterDetailLevel dwDefaultDetailLevel;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szDialogBoxCaption;
    }

    public static class PDH_COUNTER_INFO
    {
        /// <summary>
        /// This version of the struct is for general use, and is not intended for marshaling.
        /// </summary>
        [DebuggerDisplay("{szFullPath}")]
        public class Managed
        {
            public PerformanceCounterType dwType;
            public uint CVersion;
            public PDH_STATUS CStatus;
            public int lScale;
            public int lDefaultScale;
            public UINT_PTR dwUserData;
            public UINT_PTR dwQueryUserData;
            public string szFullPath;
            public PDH_COUNTER_PATH_ELEMENTS.Hydrated CounterPath;
            public string szExplainText;
        }

        /// <summary>
        /// This version of the struct is for reading back as part of a buffer.
        /// </summary>
        [DebuggerDisplay("{szFullPath}")]
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Flat
        {
            public uint dwLength;
            public PerformanceCounterType dwType;
            public uint CVersion;
            public PDH_STATUS CStatus;
            public int lScale;
            public int lDefaultScale;
            public UINT_PTR dwUserData;
            public UINT_PTR dwQueryUserData;
            public UINT_PTR szFullPath;
            public PDH_COUNTER_PATH_ELEMENTS.Flat CounterPath;
            public UINT_PTR szExplainText;
        }
    }

    public static class PDH_COUNTER_PATH_ELEMENTS
    {
        static PDH_COUNTER_PATH_ELEMENTS()
        {
            Debug.Assert(MarshalHelper.SizeOf<Hydrated>() == MarshalHelper.SizeOf<Flat>());
        }

        /// <summary>
        /// This version of the struct is for writing and general use.
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Hydrated
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string szMachineName;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string szObjectName;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string szInstanceName;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string szParentInstance;
            public uint dwInstanceIndex;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string szCounterName;
        }

        /// <summary>
        /// This version of the struct is for reading back as part of a buffer.
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Flat
        {
            public UINT_PTR szMachineName;
            public UINT_PTR szObjectName;
            public UINT_PTR szInstanceName;
            public UINT_PTR szParentInstance;
            public uint dwInstanceIndex;
            public UINT_PTR szCounterName;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_DATA_ITEM_PATH_ELEMENTS
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szMachineName;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid ObjectGUID;
        public uint dwItemId;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szInstanceName;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_FMT_COUNTERVALUE
    {
        public PDH_STATUS CStatus;

        [StructLayout(LayoutKind.Explicit)]
        public struct DUMMYUNIONNAME
        {
            [FieldOffset(0)]
            public int longValue;
            [FieldOffset(0)]
            public double doubleValue;
            [FieldOffset(0)]
            public ulong largeValue;
            [FieldOffset(0)]
            public UINT_PTR AnsiStringValue;
            [FieldOffset(0)]
            public UINT_PTR WideStringValue;
        }

        /// <summary>The native implementation uses an anonymous union.</summary>
        public DUMMYUNIONNAME _valueUnion;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_FMT_COUNTERVALUE_ITEM
    {
        /// <summary>
        /// Absolute pointer to a null-terminated string that specifies the instance name of the counter.
        /// The string is appended to the end of this structure.
        /// The semantics of PdhGetFormattedCounterArray() prevent us from marshaling this as an ordinary string.
        /// </summary>
        public UINT_PTR szName;
        public PDH_FMT_COUNTERVALUE FmtValue;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct PDH_HCOUNTER
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static PDH_HCOUNTER NULL = default(PDH_HCOUNTER);

        public bool IsNull
        {
            get { unsafe { return (_handle == null); } }
        }

        public override string ToString()
        {
            unsafe
            {
                return ((UINT_PTR)_handle).ToString();
            }
        }
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct PDH_HQUERY
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static PDH_HQUERY NULL = default(PDH_HQUERY);

        public bool IsNull
        {
            get { unsafe { return (_handle == null); } }
        }

        public override string ToString()
        {
            unsafe
            {
                return ((UINT_PTR)_handle).ToString();
            }
        }
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct PDH_HLOG
    {
        [FieldOffset(0)]
        private unsafe void* _handle;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_RAW_COUNTER
    {
        public volatile PDH_STATUS CStatus;
        public FILETIME TimeStamp;
        public long FirstValue;
        public long SecondValue;
        public uint MultiCount;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_RAW_COUNTER_ITEM
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string szName;
        public PDH_RAW_COUNTER RawValue;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_STATISTICS
    {
        public PdhFormat dwFormat;
        public uint count;
        public PDH_FMT_COUNTERVALUE min;
        public PDH_FMT_COUNTERVALUE max;
        public PDH_FMT_COUNTERVALUE mean;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PDH_TIME_INFO
    {
        public long StartTime;
        public long EndTime;
        public uint SampleCount;
    } 

    [DebuggerDisplay("{ByteLength} bytes")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]
    public struct PERF_COUNTER_BLOCK
    {
        public uint ByteLength;         // Length in bytes of this structure, including the following counters
    }

    [DebuggerDisplay("{ByteLength} bytes")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]
    public struct PERF_COUNTER_DEFINITION
    {
        public uint ByteLength;         // Length in bytes of this structure
        public uint CounterNameTitleIndex; // Index of Counter name into Title Database
        public uint CounterNameTitle; // LPWSTR in 32-bit, offset in anything higher. Initially NULL, for use by analysis program to point to retrieved title string
        public uint CounterHelpTitleIndex; // Index of Counter Help into Title Database
        public uint CounterHelpTitle; // LPWSTR in 32-bit, offset in anything higher. Initially NULL, for use by analysis program to point to retrieved title string
        public int DefaultScale;       // Power of 10 by which to scale chart line if vertical axis is 100 0 ==> 1, 1 ==> 10, -1 ==>1/10, etc.
        public PerformanceCounterDetailLevel DetailLevel;        // Counter level of detail (for controlling display complexity)
        public PerformanceCounterType CounterType;        // Type of counter
        public uint CounterSize;        // Size of counter in bytes
        public uint CounterOffset;      // Offset from the start of the PERF_COUNTER_BLOCK to the first byte of this counter
    }

    [DebuggerDisplay("{ByteLength} bytes, {NumObjectTypes} categories")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]
    public struct PERF_DATA_BLOCK
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
        public string Signature;       // Signature: Unicode "PERF"
        public uint LittleEndian;       // 0 = Big Endian, 1 = Little Endian
        public uint Version;            // Version of these data structures starting at 1
        public uint Revision;           // Revision of these data structures starting at 0 for each Version
        public uint TotalByteLength;    // Total length of data block
        public uint HeaderLength;       // Length of this structure
        public uint NumObjectTypes;     // Number of types of objects being reported
        public int DefaultObject;      // Object Title Index of default object to display when data from this system is retrieved (-1 = none, but this is not expected to be used)
        public SYSTEMTIME SystemTime;         // Time at the system under measurement
        public LARGE_INTEGER PerfTime;           // Performance counter value at the system under measurement
        public LARGE_INTEGER PerfFreq;           // Performance counter frequency at the system under measurement
        public LARGE_INTEGER PerfTime100nSec;    // Performance counter time in 100 nsec units at the system under measurement
        public uint SystemNameLength;   // Length of the system name
        public uint SystemNameOffset;   // Offset, from beginning of this structure, to name of system being measured
    }

    [DebuggerDisplay("{ByteLength} bytes")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]
    public struct PERF_INSTANCE_DEFINITION
    {
        public uint ByteLength;         // Length in bytes of this structure, including the subsequent name
        public uint ParentObjectTitleIndex; // Title Index to name of "parent" object (e.g., if thread, then process is parent object type); if logical drive, the physical drive is parent object type
        public uint ParentObjectInstance; // Index to instance of parent object type which is the parent of this instance.
        public int UniqueID;           // A unique ID used instead of matching the name to identify this instance, -1 = none
        public uint NameOffset;         // Offset from beginning of this struct to the Unicode name of this instance
        public uint NameLength;         // Length in bytes of name; 0 = none this length includes the characters in the string plus the size of the terminating NULL char. It does not include any additional pad bytes to correct structure alignment
    }

    [DebuggerDisplay("{TotalByteLength} bytes ({HeaderLength} header, {DefinitionLength} definition)")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 8)]
    public struct PERF_OBJECT_TYPE
    {
        public uint TotalByteLength;    // Length of this object definition including this structure, the counter definitions, and the instance definitions and the counter blocks for each instance: This is the offset from this structure to the next object, if any
        public uint DefinitionLength;   // Length of object definition, which includes this structure and the counter definition structures for this object: this is the offset of the first instance or of the counters for this object if there is no instance
        public uint HeaderLength;       // Length of this structure: this is the offset to the first counter definition for this object
        public uint ObjectNameTitleIndex; // Index to name in Title Database
        public uint ObjectNameTitle;    // LPWSTR in 32-bit, offset in anything higher. Initially NULL, for use by analysis program to point to retrieved title string
        public uint ObjectHelpTitleIndex; // Index to Help in Title Database
        public uint ObjectHelpTitle; // LPWSTR in 32-bit, offset in anything higher. Initially NULL, for use by analysis program to point to retrieved title string
        public PerformanceCounterDetailLevel DetailLevel;        // Object level of detail (for controlling display complexity); will be min of detail levels for all this object's counters
        public uint NumCounters;        // Number of counters in each counter block (one counter block per instance)
        public uint DefaultCounter;     // Default counter to display when this object is selected, index starting at 0 (-1 = none, but this is not expected to be used)
        public int NumInstances;       // Number of object instances for which counters are being returned from the system under measurement. If the object defined will never have any instance data structures (PERF_INSTANCE_DEFINITION) then this value should be -1, if the object can have 0 or more instances, but has none present, then this should be 0, otherwise this field contains the number of instances of this counter.
        public uint CodePage;           // 0 if instance strings are in UNICODE, else the Code Page of the instance names
        public LARGE_INTEGER PerfTime;           // Sample Time in "Object" units
        public LARGE_INTEGER PerfFreq;           // Frequency of "Object" units in counts per second.
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PERFORMANCE_INFORMATION
    {
        public uint cb;
        public UINT_PTR CommitTotal;
        public UINT_PTR CommitLimit;
        public UINT_PTR CommitPeak;
        public UINT_PTR PhysicalTotal;
        public UINT_PTR PhysicalAvailable;
        public UINT_PTR SystemCache;
        public UINT_PTR KernelTotal;
        public UINT_PTR KernelPaged;
        public UINT_PTR KernelNonpaged;
        public UINT_PTR PageSize;
        public uint HandleCount;
        public uint ProcessCount;
        public uint ThreadCount;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct POINT
    {
        public int x;
        public int y;

        public POINT(int X, int Y)
        {
            x = X;
            y = Y;
            return;
        }

        public override string ToString()
        {
            return string.Format("({0}, {1})", x, y);
        }

        /// <summary>
        /// Converter into a message LPARAM.
        /// </summary>
        public static implicit operator IntPtr(POINT pt)
        {
            return (IntPtr)(uint)pt;
        }

        /// <summary>
        /// Converter from a message LPARAM.
        /// </summary>
        public static implicit operator POINT(UINT_PTR iValue)
        {
            return (POINT)(uint)iValue;
        }

        public static implicit operator uint(POINT pt)
        {
            return (uint)(((ushort)pt.y << 16) | (ushort)pt.x);
        }

        public static implicit operator POINT(uint uiValue)
        {
            int x = (short)(uiValue & 0xFFFF);
            int y = (short)((uiValue >> 16) & 0xFFFF);
            return new POINT(x, y);
        }

        /// <summary>
        /// Converter from WPF.
        /// </summary>
        public static implicit operator POINT(System.Windows.Point pt)
        {
            return new POINT((int)pt.X, (int)pt.Y);
        }

        /// <summary>
        /// Converter from WinForms.
        /// </summary>
        public static implicit operator POINT(System.Drawing.Point pt)
        {
            return new POINT(pt.X, pt.Y);
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct POINTL
    {
        public int y;
        public int x;
    }

    /// <summary>
    /// POINTS isn't plural, it means POINT-expressed-as-SHORT (as opposed to the INT coordinates of a normal POINT).
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct POINTS
    {
        public short y;
        public short x;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct PROCESS_HEAP_ENTRY
    {
        public UINT_PTR lpData;
        public uint cbData;
        public byte cbOverhead;
        public byte iRegionIndex;
        public ProcessHeapFlags wFlags;

        /// <summary>What a mess.</summary>
        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
        public struct _outer_union
        {
            /// <summary>What a mess.</summary>
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct _Block
            {
                public HANDLE hMem;
                public fixed uint dwReserved[3];
            }
            [FieldOffset(0)]
            public _Block Block;

            /// <summary>What a mess.</summary>
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct _Region
            {
                public uint dwCommittedSize;
                public uint dwUnCommittedSize;
                public UINT_PTR lpFirstBlock;
                public UINT_PTR lpLastBlock;
            }
            [FieldOffset(0)]
            public _Region Region;
        }

        public _outer_union outer_union;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PROCESS_INFORMATION : IDisposable
    {
        public HANDLE hProcess;
        public HANDLE hThread;
        public int dwProcessId;
        public int dwThreadId;

        public void Dispose()
        {
            if (!hProcess.IsNullOrInvalid)
                if (!KERNEL32.CloseHandle(hProcess))
                    throw new Win32Exception();
            hProcess = HANDLE.NULL;

            if (!hThread.IsNullOrInvalid)
                if (!KERNEL32.CloseHandle(hThread))
                    throw new Win32Exception();
            hThread = HANDLE.NULL;

            return;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PROCESSENTRY32
    {
        public uint dwSize;
        public uint cntUsage;
        public uint th32ProcessID;
        public UINT_PTR th32DefaultHeapID;
        public uint th32ModuleID;
        public uint cntThreads;
        public uint th32ParentProcessID;
        public int pcPriClassBase;
        public uint dwFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_PATH)]
        public string szExeFile;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PROCESSOR_NUMBER
    {
        public ushort Group;
        public byte Number;
        public byte Reserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PROCESS_BASIC_INFORMATION
    {
        public int ExitStatus;
        public UINT_PTR PebBaseAddress;
        public UINT_PTR AffinityMask;
        public int BasePriority;
        public UINT_PTR UniqueProcessId;
        public UINT_PTR InheritedFromUniqueProcessId;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PROPERTYKEY
    {
        public Guid fmtid;
        public uint pid;

        public PROPERTYKEY(Guid new_fmtid, uint new_pid)
        {
            fmtid = new_fmtid;
            pid = new_pid;
            return;
        }

        public static bool operator ==(PROPERTYKEY pk1, PROPERTYKEY pk2)
        {
            return (pk1.pid == pk2.pid) && (pk1.fmtid == pk2.fmtid);
        }

        public static bool operator !=(PROPERTYKEY pk1, PROPERTYKEY pk2)
        {
            return (pk1.pid != pk2.pid) || (pk1.fmtid != pk2.fmtid);
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PROPVARIANT
    {
        // TODO: Good luck with this monster.
    }

    [StructLayout(LayoutKind.Explicit)]
    public struct PTP_CALLBACK_INSTANCE
    {
        [FieldOffset(0)]
        private unsafe void* _handle;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PUBLIC_OBJECT_BASIC_INFORMATION
    {
        public uint Attributes;
        public uint GrantedAccess; // ACCESS_MASK
        public uint HandleCount;
        public uint PointerCount;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        private uint[] Reserved;    // reserved for internal use
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PUBLIC_OBJECT_TYPE_INFORMATION
    {
        public UNICODE_STRING TypeName;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 22)]
        private uint[] Reserved;    // reserved for internal use
    }

    public static class QUERY_SERVICE_CONFIG
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct Raw
        {
            public ServiceType dwServiceType;
            public ServiceStartType dwStartType;
            public ServiceErrorControl dwErrorControl;
            public UINT_PTR lpBinaryPathName;
            public UINT_PTR lpLoadOrderGroup;
            public uint dwTagId;
            public UINT_PTR lpDependencies;
            public UINT_PTR lpServiceStartName;
            public UINT_PTR lpDisplayName;
        }

        public struct Managed
        {
            public ServiceType dwServiceType;
            public ServiceStartType dwStartType;
            public ServiceErrorControl dwErrorControl;
            public string lpBinaryPathName;
            public string lpLoadOrderGroup;
            public uint dwTagId;
            public string lpDependencies;
            public string lpServiceStartName;
            public string lpDisplayName;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct RAWHID
    {
        public uint dwSizeHid;
        public uint dwCount;
        public fixed byte bRawData[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct RAWINPUT
    {
        public RAWINPUTHEADER header;

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
        public struct _UNION
        {
            [FieldOffset(0)]
            public RAWMOUSE mouse;
            [FieldOffset(0)]
            public RAWKEYBOARD keyboard;
            [FieldOffset(0)]
            public RAWHID hid;
        }

        public _UNION data;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct RAWINPUTDEVICE
    {
        public ushort usUsagePage;
        public ushort usUsage;
        public RawInputDeviceFlags dwFlags;
        public HWND hwndTarget;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct RAWINPUTHEADER
    {
        public uint dwType;
        public uint dwSize;
        public HANDLE hDevice;
        public UINT_PTR wParam;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct RAWKEYBOARD
    {
        public ushort MakeCode;
        public ushort Flags;
        public ushort Reserved;
        public ushort VKey;
        public uint Message;
        public uint ExtraInformation;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct RAWMOUSE
    {
        [FieldOffset(0)]
        public ushort usFlags;
        [FieldOffset(2)]
        public uint ulButtons;
        [FieldOffset(2)]
        public ushort usButtonFlags;
        [FieldOffset(4)]
        public ushort usButtonData;
        [FieldOffset(6)]
        public uint ulRawButtons;
        [FieldOffset(10)]
        public int lLastX;
        [FieldOffset(14)]
        public int lLastY;
        [FieldOffset(18)]
        public uint ulExtraInformation;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;

        public int Width
        {
            get { return right - left; }
        }

        public int Height
        {
            get { return bottom - top; }
        }

        public RECT(int iLeft, int iTop, int iRight, int iBottom)
        {
            left = iLeft;
            top = iTop;
            right = iRight;
            bottom = iBottom;
            return;
        }

        public override string ToString()
        {
            return string.Format("({0}, {1})-({2}, {3})", left, top, right, bottom);
        }

        /// <summary>
        /// Converter from WPF.
        /// </summary>
        public static implicit operator RECT(System.Windows.Int32Rect rc)
        {
            return new RECT(rc.X, rc.Y, rc.X + rc.Width, rc.Y + rc.Height);
        }

        /// <summary>
        /// Converter from WPF.
        /// </summary>
        public static implicit operator RECT(System.Windows.Rect rc)
        {
            return new RECT((int)rc.Left, (int)rc.Top, (int)rc.Right, (int)rc.Bottom);
        }

        /// <summary>
        /// Converter from WinForms.
        /// </summary>
        public static implicit operator RECT(System.Drawing.Rectangle rc)
        {
            return new RECT(rc.Left, rc.Top, rc.Right, rc.Bottom);
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct RTL_USER_PROCESS_PARAMETERS
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public byte[] Reserved1;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public UINT_PTR[] Reserved2;
        public UNICODE_STRING ImagePathName;
        public UNICODE_STRING CommandLine;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct SAFEARRAY
    {
        public ushort cDims;
        public ushort fFeatures;
        public uint cbElements;
        public uint cLocks;
        public UINT_PTR pvData;
        /// <summary>Pointer to an array of SAFEARRAYBOUND.</summary>
        public UINT_PTR rgsabound;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public struct SAFEARRAYBOUND
    {
        public uint cElements;
        public int lLbound;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SC_ACTION
    {
        public SC_ACTION_TYPE Type;
        public uint Delay;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SECURITY_ATTRIBUTES
    {
        public int nLength;
        public UINT_PTR lpSecurityDescriptor;
        [MarshalAs(UnmanagedType.Bool)]
        public bool bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SERVICE_DESCRIPTION
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpDescription;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SERVICE_FAILURE_ACTIONS
    {
        public uint dwResetPeriod;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpRebootMsg;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpCommand;
        public uint cActions;
        public UINT_PTR lpsaActions;
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct SERVICE_STATUS_HANDLE
    {
        [FieldOffset(0)]
        private unsafe void* _handle;

        public static readonly SERVICE_STATUS_HANDLE NULL = default(SERVICE_STATUS_HANDLE);
        public bool IsNull
        {
            get { unsafe { return (_handle == null); } }
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct SERVICE_STATUS
    {
        public ServiceType dwServiceType;
        public ServiceState dwCurrentState;
        public ServiceControlsAccepted dwControlsAccepted;
        public uint dwWin32ExitCode;
        public Win32ErrorCode dwServiceSpecificExitCode;
        public uint dwCheckPoint;
        public uint dwWaitHint;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct SERVICE_STATUS_PROCESS
    {
        public ServiceType dwServiceType;
        public ServiceState dwCurrentState;
        public ServiceControlsAccepted dwControlsAccepted;
        public uint dwWin32ExitCode;
        public Win32ErrorCode dwServiceSpecificExitCode;
        public uint dwCheckPoint;
        public uint dwWaitHint;
        public uint dwProcessId;
        public ServiceFlags dwServiceFlags;
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SERVICE_TABLE_ENTRY
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpServiceName;
        public SERVICE_MAIN_FUNCTION lpServiceProc;
    };

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHARDAPPIDINFO
    {
        public IShellItem psi;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszAppID;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHARDAPPIDINFOIDLIST
    {
        /// <summary>This is actually an LPITEMIDLIST.</summary>
        public IntPtr pidl;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszAppID;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHARDAPPIDINFOLINK
    {
        public IShellLinkW psl;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszAppID;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHChangeNotifyEntry
    {
        public IntPtr pidl;
        public bool fRecursive;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHFILEOPSTRUCT
    {
        public HWND hwnd;
        public ShellFileOperationCode wFunc;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pFrom;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pTo;
        public FILEOP_FLAGS fFlags;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fAnyOperationsAborted;
        public UINT_PTR hNameMappings;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpszProgressTitle;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public unsafe struct SHITEMID
    {
        [FieldOffset(0)]
        public ushort cb;
        [FieldOffset(2)]
        public fixed byte abID[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SHQUERYRBINFO
    {
        public uint cbSize;
        public long i64Size;
        public long i64NumItems;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public unsafe struct SID
    {
        public byte Revision;
        public byte SubAuthorityCount;
        public SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
        public fixed uint SubAuthority[1];
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SID_IDENTIFIER_AUTHORITY
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] Value;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFO
    {
        public int cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public int dwX;
        public int dwY;
        public int dwXSize;
        public int dwYSize;
        public int dwXCountChars;
        public int dwYCountChars;
        public int dwFillAttribute;
        public int dwFlags;
        public short wShowWindow;
        public short cbReserved2;
        public UINT_PTR lpReserved2;
        public HANDLE hStdInput;
        public HANDLE hStdOutput;
        public HANDLE hStdError;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFOEX
    {
        public STARTUPINFO StartupInfo;
        public UINT_PTR lpAttributeList; //TODO:
    }

    public struct STGMEDIUM
    {
        public TYMED tymed;
        private UINT_PTR u; // union
        /*public HBITMAP hBitmap
        {
            get { return new HBITMAP { _handle = u }; }
            set {                STGMEDIUM }
        }
        HMETAFILEPICT hMetaFilePict;
        HENHMETAFILE hEnhMetaFile;
        HGLOBAL hGlobal;
        public LPOLESTR lpszFileName
        {
            get { }
        }
        public IStream pstm
        {
            get { return (Marshal.GetObjectForIUnknown(u) as IStorage); }
        }
        public IStorage pstg
        {
            get { return (Marshal.GetObjectForIUnknown(u) as IStorage); }
        }*/
        public IUnknown pUnkForRelease;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public unsafe struct STRRET
    {
        [FieldOffset(0)]
        public STRRET_TYPE uType;
        [FieldOffset(4)]
        public char* pOleStr;    // must be freed by caller of GetDisplayNameOf
        [FieldOffset(4)]
        public UINT_PTR pStr;        // NOT USED
        [FieldOffset(4)]
        public uint uOffset;    // Offset into SHITEMID
        [FieldOffset(4)]
        public fixed sbyte cStr[260];        // Buffer to fill in (ANSI)
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SWbemQueryQualifiedName
    {
        public uint m_uVersion;
        public uint m_uTokenType;
        public uint m_uNameListSize;
        public UINT_PTR m_ppszNameList;
        [MarshalAs(UnmanagedType.Bool)]
        public bool m_bArraysUsed;
        /// <summary>Pointer to an array of BOOL.</summary>
        public UINT_PTR m_pbArrayElUsed;
        /// <summary>Pointer to an array of UINT.</summary>
        public UINT_PTR m_puArrayIndex;

        public override string ToString()
        {
            UINT_PTR[] names = MarshalHelper.PtrToStructureArray<UINT_PTR>(m_ppszNameList, m_uNameListSize);
            return names.Select(psz => Marshal.PtrToStringUni(psz)).Join(", ");
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SWbemRpnEncodedQuery
    {
        public uint m_uVersion;
        public uint m_uTokenType;
        public ulong m_uParsedFeatureMask;
        public uint m_uDetectedArraySize;
        /// <summary>Pointer to an array of UINT.</summary>
        public UINT_PTR m_puDetectedFeatures;
        public uint m_uSelectListSize;
        /// <summary>Pointer to an array of <see cref="SWbemQueryQualifiedName"/> pointers.</summary>
        public UINT_PTR m_ppSelectList;
        public uint m_uFromTargetType;
        public UINT_PTR m_pszOptionalFromPath;
        public uint m_uFromListSize;
        /// <summary>Pointer to an array of string pointers.</summary>
        public UINT_PTR m_ppszFromList;
        public uint m_uWhereClauseSize;
        /// <summary>Pointer to an array of <see cref="SWbemRpnQueryToken"/> pointers.</summary>
        public UINT_PTR m_ppRpnWhereClause;
        public double m_dblWithinPolling;
        public double m_dblWithinWindow;

        public override string ToString()
        {
            if (m_pszOptionalFromPath != UINT_PTR.Zero)
                return Marshal.PtrToStringUni(m_pszOptionalFromPath);
            else
            {
                UINT_PTR[] sources = MarshalHelper.PtrToStructureArray<UINT_PTR>(m_ppszFromList, m_uFromListSize);
                return sources.Select(psz => Marshal.PtrToStringUni(psz)).Join(", ");
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SWbemRpnQueryToken
    {
        public uint m_uVersion;
        public uint m_uTokenType;
        public uint m_uSubexpressionShape;
        public uint m_uOperator;
        /// <summary>Pointer to <see cref="SWbemQueryQualifiedName"/>.</summary>
        public UINT_PTR m_pRightIdent;
        /// <summary>Pointer to <see cref="SWbemQueryQualifiedName"/>.</summary>
        public UINT_PTR m_pLeftIdent;
        public uint m_uConstApparentType;
        public SWbemRpnConst m_Const;
        public uint m_uConst2ApparentType;
        public SWbemRpnConst m_Const2;
        public UINT_PTR m_pszRightFunc;
        public UINT_PTR m_pszLeftFunc;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct SWbemRpnConst
    {
        [FieldOffset(0)]
        public UINT_PTR m_pszStrVal;
        [FieldOffset(0), MarshalAs(UnmanagedType.Bool)]
        public bool m_bBoolVal;
        [FieldOffset(0)]
        public int m_lLongVal;
        [FieldOffset(0)]
        public uint m_uLongVal;
        [FieldOffset(0)]
        public double m_dblVal;
        [FieldOffset(0)]
        public long m_lVal64;
        [FieldOffset(0)]
        public ulong m_uVal64;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SYSTEM_INFO
    {
        public ProcessorArchitecture wProcessorArchitecture;
        public ushort wReserved;
        public uint dwPageSize;
        public UINT_PTR lpMinimumApplicationAddress;
        public UINT_PTR lpMaximumApplicationAddress;
        public UINT_PTR dwActiveProcessorMask;
        public uint dwNumberOfProcessors;
        public uint dwProcessorType;
        public uint dwAllocationGranularity;
        public ushort wProcessorLevel;
        public ushort wProcessorRevision;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct SYSTEMTIME
    {
        public ushort wYear;
        public ushort wMonth;
        public ushort wDayOfWeek;
        public ushort wDay;
        public ushort wHour;
        public ushort wMinute;
        public ushort wSecond;
        public ushort wMilliseconds;

        public override string ToString()
        {
            FILETIME fileTime;
            if (!KERNEL32.SystemTimeToFileTime(ref this, out fileTime))
                throw new Win32Exception();
            return fileTime.ToString();
        }
    }

    /// <summary>
    /// NOTE: Packing must be set to 4 to make this work on 64-bit platforms.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)]
    public struct TASKDIALOG_BUTTON
    {
        public TASKDIALOG_BUTTON(int n, string txt)
        {
            nButtonID = n;
            pszButtonText = txt;
        }

        public int nButtonID;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pszButtonText;
    }

    [Flags]
    public enum TASKDIALOG_FLAGS : int
    {
        TDF_ENABLE_HYPERLINKS = 0x0001,
        TDF_USE_HICON_MAIN = 0x0002,
        TDF_USE_HICON_FOOTER = 0x0004,
        TDF_ALLOW_DIALOG_CANCELLATION = 0x0008,
        TDF_USE_COMMAND_LINKS = 0x0010,
        TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020,
        TDF_EXPAND_FOOTER_AREA = 0x0040,
        TDF_EXPANDED_BY_DEFAULT = 0x0080,
        TDF_VERIFICATION_FLAG_CHECKED = 0x0100,
        TDF_SHOW_PROGRESS_BAR = 0x0200,
        TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400,
        TDF_CALLBACK_TIMER = 0x0800,
        TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000,
        TDF_RTL_LAYOUT = 0x2000,
        TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000,
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct TASKDIALOGCONFIG_ICON_UNION
    {
        [FieldOffset(0)]
        public int hMainIcon;
        [FieldOffset(0)]
        public int pszIcon;

        /// <summary>
        /// NOTE: We include a "spacer" so that the struct size varies on 64-bit architectures.
        /// </summary>
        [FieldOffset(0)]
        private UINT_PTR spacer;
    }

    /// <summary>
    /// Main task dialog configuration struct.
    /// NOTE: Packing must be set to 4 to make this work on 64-bit platforms.
    /// ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/shellcc/platform/commctls/taskdialogs/taskdialogreference/taskdialogstructures/taskdialogconfig.htm
    /// </summary>
    public class TASKDIALOGCONFIG
    {
        public class Managed
        {
            public HWND hwndParent;
            public HINSTANCE hInstance;
            public TASKDIALOG_FLAGS dwFlags;
            public TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszWindowTitle;
            public TASKDIALOGCONFIG_ICON_UNION MainIcon; // NOTE: 32-bit union field, holds pszMainIcon as well
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszMainInstruction;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszContent;
            public IEnumerable<TASKDIALOG_BUTTON> pButtons;
            public int nDefaultButton;
            public IEnumerable<TASKDIALOG_BUTTON> pRadioButtons;
            public int nDefaultRadioButton;
            public string pszVerificationText;
            public string pszExpandedInformation;
            public string pszExpandedControlText;
            public string pszCollapsedControlText;
            public TASKDIALOGCONFIG_ICON_UNION FooterIcon;  // NOTE: 32-bit union field, holds pszFooterIcon as well
            public string pszFooter;
            public TASKDIALOGCALLBACK pfCallback;
            public uint cxWidth;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 4)]
        public struct Native
        {
            public uint cbSize; //cbSize = (uint)Marshal.SizeOf(typeof(TASKDIALOGCONFIG));
            public HWND hwndParent;
            public HINSTANCE hInstance;
            public TASKDIALOG_FLAGS dwFlags;
            public TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszWindowTitle;
            public TASKDIALOGCONFIG_ICON_UNION MainIcon; // NOTE: 32-bit union field, holds pszMainIcon as well
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszMainInstruction;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszContent;
            public uint cButtons;
            public /*TASKDIALOG_BUTTON[]*/ UINT_PTR pButtons;           // Ptr to TASKDIALOG_BUTTON structs
            public int nDefaultButton;
            public uint cRadioButtons;
            public /*TASKDIALOG_BUTTON[]*/ UINT_PTR pRadioButtons;      // Ptr to TASKDIALOG_BUTTON structs
            public int nDefaultRadioButton;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszVerificationText;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszExpandedInformation;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszExpandedControlText;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszCollapsedControlText;
            public TASKDIALOGCONFIG_ICON_UNION FooterIcon;  // NOTE: 32-bit union field, holds pszFooterIcon as well
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pszFooter;
            public UINT_PTR pfCallback;
            public UINT_PTR lpCallbackData;
            public uint cxWidth;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct THREADENTRY32
    {
        public uint dwSize;
        public uint cntUsage;
        public uint th32ThreadID;
        public uint th32OwnerProcessID;
        public int tpBasePri;
        public int tpDeltaPri;
        public uint dwFlags;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TIME_OF_DAY_INFO
    {
        public uint tod_elapsedt;
        public uint tod_msecs;
        public uint tod_hours;
        public uint tod_mins;
        public uint tod_secs;
        public uint tod_hunds;
        public int tod_timezone;
        public uint tod_tinterval;
        public uint tod_day;
        public uint tod_month;
        public uint tod_year;
        public uint tod_weekday;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TIME_ZONE_INFORMATION
    {
        public int Bias;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string StandardName;
        public SYSTEMTIME StandardDate;
        public int StandardBias;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string DaylightName;
        public SYSTEMTIME DaylightDate;
        public int DaylightBias;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TOUCHINPUT
    {
        public int x;
        public int y;
        public HANDLE hSource;
        public uint dwID;
        public TouchEventFlags dwFlags;
        public TouchInputMask dwMask;
        public uint dwTime;
        public UINT_PTR dwExtraInfo;
        public uint cxContact;
        public uint cyContact;
    }

    /// <summary>
    /// Thread pool callback priorities for Windows 7 and later.
    /// </summary>
    public enum TP_CALLBACK_PRIORITY : int
    {
        TP_CALLBACK_PRIORITY_HIGH = 0,
        TP_CALLBACK_PRIORITY_NORMAL = 1,
        TP_CALLBACK_PRIORITY_LOW = 2,
        TP_CALLBACK_PRIORITY_INVALID = 3,
    }

    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct TP_CALLBACK_ENVIRON
    {
        public uint Version;
        public UINT_PTR /* PTP_POOL */ Pool;
        public UINT_PTR /* PTP_CLEANUP_GROUP */ CleanupGroup;
        //[MarshalAs(UnmanagedType.FunctionPtr)]
        public IntPtr /* PTP_CLEANUP_GROUP_CANCEL_CALLBACK */ CleanupGroupCancelCallback;
        public HINSTANCE RaceDll;
        public UINT_PTR ActivationContext;
        //[MarshalAs(UnmanagedType.FunctionPtr)]
        public IntPtr /* PTP_SIMPLE_CALLBACK */ FinalizationCallback;
        /*
            DWORD                      LongFunction :  1;
            DWORD                      Persistent   :  1;
            DWORD                      Private      : 30;
         */
        public uint Flags;

        //  After Win7
        public TP_CALLBACK_PRIORITY CallbackPriority;
        public uint Size;
    }

    /// <summary>
    /// Thread pool callback environment for Windows Vista and later.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct TP_CALLBACK_ENVIRON_V1
    {
        public uint Version;
        public UINT_PTR /* PTP_POOL */ Pool;
        public UINT_PTR /* PTP_CLEANUP_GROUP */ CleanupGroup;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback;
        public HINSTANCE RaceDll;
        public UINT_PTR ActivationContext;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public PTP_SIMPLE_CALLBACK FinalizationCallback;
        /*
            DWORD                      LongFunction :  1;
            DWORD                      Persistent   :  1;
            DWORD                      Private      : 30;
         */
        public uint Flags;

        //  After Win7
        //public TP_CALLBACK_PRIORITY CallbackPriority;
        //public uint Size;
    }

    /// <summary>
    /// Thread pool callback environment for Windows 7 and later.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct TP_CALLBACK_ENVIRON_V3
    {
        public uint Version;
        public UINT_PTR /* PTP_POOL */ Pool;
        public UINT_PTR /* PTP_CLEANUP_GROUP */ CleanupGroup;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback;
        public HINSTANCE RaceDll;
        public UINT_PTR ActivationContext;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public PTP_SIMPLE_CALLBACK FinalizationCallback;
        /*
            DWORD                      LongFunction :  1;
            DWORD                      Persistent   :  1;
            DWORD                      Private      : 30;
         */
        public uint Flags;

        //  After Win7
        public TP_CALLBACK_PRIORITY CallbackPriority;
        public uint Size;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRACE_ENABLE_INFO
    {
        public uint IsEnabled;
        public TraceLevel Level;
        public byte Reserved1;
        public ushort LoggerId;
        public uint EnableProperty;
        public uint Reserved2;
        public ulong MatchAnyKeyword;
        public ulong MatchAllKeyword;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRACE_GUID_INFO
    {
        public uint InstanceCount;
        public uint Reserved;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRACE_GUID_PROPERTIES
    {
        [MarshalAs(UnmanagedType.Struct)]
        public Guid Guid;
        public uint GuidType;
        public uint LoggerId;
        public uint EnableLevel;
        public uint EnableFlags;
        public BOOLEAN IsEnable;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRACE_GUID_REGISTRATION
    {
        [MarshalAs(UnmanagedType.Struct)]
        public Guid Guid;            // Guid of data block being registered or updated.
        public HANDLE RegHandle;        // Guid Registration Handle is returned.
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRACE_LOGFILE_HEADER
    {
        public uint BufferSize;

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME
        {
            [FieldOffset(0)]
            public uint Version;

            [StructLayout(LayoutKind.Sequential)]
            public struct _VersionDetail
            {
                public byte MajorVersion;
                public byte MinorVersion;
                public byte SubVersion;
                public byte SubMinorVersion;
            }
            [FieldOffset(0)]
            public _VersionDetail VersionDetail;
        }
        public _DUMMYUNIONNAME DUMMYUNIONNAME;

        public uint ProviderVersion;    // defaults to NT version
        public uint NumberOfProcessors; // Number of Processors
        public LARGE_INTEGER EndTime;            // Time when logger stops
        public uint TimerResolution;    // assumes timer is constant!!!
        public uint MaximumFileSize;    // Maximum in Mbytes
        public uint LogFileMode;        // specify logfile mode
        public uint BuffersWritten;     // used to file start of Circular File

        [StructLayout(LayoutKind.Explicit)]
        public struct _DUMMYUNIONNAME2
        {
            [FieldOffset(0), MarshalAs(UnmanagedType.Struct)]
            public Guid LogInstanceGuid;

            [StructLayout(LayoutKind.Sequential)]
            public struct _DUMMYSTRUCTNAME
            {
                public uint StartBuffers;       // Count of buffers written at start.
                public uint PointerSize;        // Size of pointer type in bits
                public uint EventsLost;         // Events losts during log session
                public uint CpuSpeedInMHz;      // Cpu Speed in MHz
            }
            [FieldOffset(0)]
            public _DUMMYSTRUCTNAME DUMMYSTRUCTNAME;
        }
        public _DUMMYUNIONNAME2 DUMMYUNIONNAME2;

        [MarshalAs(UnmanagedType.LPWStr)]
        public string LoggerName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string LogFileName;
        public TIME_ZONE_INFORMATION TimeZone;
        public LARGE_INTEGER BootTime;
        public LARGE_INTEGER PerfFreq;           // Reserved
        public LARGE_INTEGER StartTime;          // Reserved
        public uint ReservedFlags;      // ClockType
        public uint BuffersLost;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRACE_PROVIDER_INSTANCE_INFO
    {
        public uint NextOffset;
        public uint EnableCount;
        public uint Pid;
        public TraceProviderFlags Flags;
    }

    [DebuggerDisplay("{_handle}")]
    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct TRACEHANDLE
    {
        [FieldOffset(0)]
        private ulong _handle;

        public static TRACEHANDLE INVALID_PROCESSTRACE_HANDLE = new TRACEHANDLE { _handle = unchecked((ulong)-1L) };

        public bool IsNull
        {
            get { return (_handle == 0); }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRANSACTION_NOTIFICATION
    {
        public UINT_PTR TransactionKey;
        public NOTIFICATION_MASK TransactionNotification;
        public LARGE_INTEGER TmVirtualClock;
        public uint ArgumentLength;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TRANSACTION_NOTIFICATION_RECOVERY_ARGUMENT
    {
        public Guid EnlistmentId;
        public Guid UOW;
    }

    [DebuggerDisplay("Length = {Length}, MaximumLength = {MaximumLength}, Buffer = {ToString()}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct UNICODE_STRING
    {
        public ushort Length;
        public ushort MaximumLength;
        public UINT_PTR Buffer;

        public static implicit operator string(UNICODE_STRING unicodeString)
        {
            return unicodeString.ToString();
        }

        public override string ToString()
        {
            return Marshal.PtrToStringUni(Buffer, Length);
        }
    }

    /// <summary>
    /// Registry value entry.
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct VALENT
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string ve_valuename;
        public uint ve_valuelen;
        public UINT_PTR ve_valueptr;
        public RegistryValueType ve_type;
    }

    [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
    public struct VARIANT
    {/*
    union 
        {
        public struct __tagVARIANT
            {
            public VARTYPE vt;
            public ushort wReserved1;
            public ushort wReserved2;
            public ushort wReserved3;
            union 
                {
                LONGLONG llVal;
                LONG lVal;
                BYTE bVal;
                SHORT iVal;
                FLOAT fltVal;
                DOUBLE dblVal;
                VARIANT_BOOL boolVal;
                SCODE scode;
                CY cyVal;
                DATE date;
                BSTR bstrVal;
                IUnknown *punkVal;
                IDispatch *pdispVal;
                SAFEARRAY *parray;
                BYTE *pbVal;
                SHORT *piVal;
                LONG *plVal;
                LONGLONG *pllVal;
                FLOAT *pfltVal;
                DOUBLE *pdblVal;
                VARIANT_BOOL *pboolVal;
                _VARIANT_BOOL *pbool;
                SCODE *pscode;
                CY *pcyVal;
                DATE *pdate;
                BSTR *pbstrVal;
                IUnknown **ppunkVal;
                IDispatch **ppdispVal;
                SAFEARRAY **pparray;
                VARIANT *pvarVal;
                PVOID byref;
                CHAR cVal;
                USHORT uiVal;
                ULONG ulVal;
                ULONGLONG ullVal;
                INT intVal;
                UINT uintVal;
                DECIMAL *pdecVal;
                CHAR *pcVal;
                USHORT *puiVal;
                ULONG *pulVal;
                ULONGLONG *pullVal;
                INT *pintVal;
                UINT *puintVal;
                struct __tagBRECORD
                    {
                    PVOID pvRecord;
                    IRecordInfo *pRecInfo;
                    } 	__VARIANT_NAME_4;
                } 	__VARIANT_NAME_3;
            } 	__VARIANT_NAME_2;
        DECIMAL decVal;
        } 	__VARIANT_NAME_1;*/
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WIN32_FILE_ATTRIBUTE_DATA
    {
        public FileFlagsAndAttributes dwFileAttributes;
        public FILETIME ftCreationTime;
        public FILETIME ftLastAccessTime;
        public FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
    }

    [DebuggerDisplay("{cFileName}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WIN32_FIND_DATA
    {
        public FileFlagsAndAttributes dwFileAttributes;
        public FILETIME ftCreationTime;
        public FILETIME ftLastAccessTime;
        public FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        private uint dwReserved0;
        private uint dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_PATH)]
        public string cFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string cAlternateFileName;
    }

    [DebuggerDisplay("{cStreamName}")]
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WIN32_FIND_STREAM_DATA
    {
        public LARGE_INTEGER StreamSize;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = Constants.MAX_PATH + 36)]
        public string cStreamName;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WINHTTP_AUTOPROXY_OPTIONS
    {
        public WinHttpAutoProxyFlags dwFlags;
        public WinHttpAutoDetectFlags dwAutoDetectFlags;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string lpszAutoConfigUrl;
        public UINT_PTR lpvReserved;
        public uint dwReserved;
        [MarshalAs(UnmanagedType.Bool)]
        public bool fAutoLogonIfChallenged;
    }

    public static class WINHTTP_PROXY_INFO
    {
        static WINHTTP_PROXY_INFO()
        {
            Debug.Assert(MarshalHelper.SizeOf<Hydrated>() == MarshalHelper.SizeOf<Flat>());
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Flat
        {
            public WinHttpProxyAccessType dwAccessType;
            public UINT_PTR lpszProxy;
            public UINT_PTR lpszProxyBypass;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct Hydrated
        {
            public WinHttpProxyAccessType dwAccessType;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpszProxy;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string lpszProxyBypass;
        }

        public struct Managed
        {
            public WinHttpProxyAccessType dwAccessType;
            public string[] lpszProxy;
            public string[] lpszProxyBypass;
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WNODE_HEADER
    {
        public uint BufferSize;
        public uint ProviderId;
        public ulong HistoricalContext;
        /// <summary>
        /// Warning: This is a union with a HANDLE, which is pointer-sized.
        /// If pointers grow larger than LARGE_INTEGER, this union will have to be explicitly implemented.
        /// </summary>
        public LARGE_INTEGER TimeStamp;
        [MarshalAs(UnmanagedType.Struct)]
        public Guid Guid;
        public uint ClientContext;
        public uint Flags;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    [DebuggerDisplay("Session={SessionId}, WinStation={pWinStationName}, State={State}")]
    public struct WTS_SESSION_INFO
    {
        public uint SessionId;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string pWinStationName;
        public WTS_CONNECTSTATE_CLASS State;
    }
}